Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 OOP Quandry
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Geminias




PostPosted: Fri May 23, 2008 6:20 pm   Post subject: OOP Quandry

Hi experienced programmers,

I'm working with a codebase that has a class heirarchy like so:

base : derived1 : derived2 : derived3 : derived4 : derived5 : derived6 : CoolObject

Some people that I'd like to call drunken dwarfs added CoolObject. It is a cool object because it was specifically designed to work with a seperate component of the system called: "CoolObjectProcessor". My goal is to get everything from derived4 onward to work with CoolObjectProcessor instead of just CoolObject.

In CoolObjectProcessor we will see something like the following:

code:

CoolObjectProcessor::doCoolProcessorShit()
{
     // CoolObjectProcessor will retrieve CoolObjects like so:
     CoolObject* iAmAssHole = dynamic_cast<CoolObject*> mBaseSet[i];

     // CoolObjectProcessor will call methods on CoolObject like so:
     iAmAssHole->doCoolShit();

    // the result is we have shitted out cool shit from our asshole.  Cool as in ice cold. 




From what I can tell mBaseSet is a set of objects of type "Base" (The superclass of all classes) Unfortunately for me mBaseSet somehow type slices the pointers it stores. Which sucks ass. (For those that don't know: type slicing removes the vtable from the pointer so you can't just use a base class to all the classes you'd like and define a virtual base method called "doCoolShit()" and expect it to call the correct method. I don't really know if type slicing "removes" the vtable, all I know is it doesn't call the method on the actual type of the ptr, it will just call the base method instead.)

I could go a few different ways with this one, but the way I'm leaning toward is multiple inheritance.

If I did something like this:

code:

class MakeACoolObject
{
    All stuff that CoolObjectProcessor requires here
}

//Then I can make any type of class that I desire to work with CoolObjectProcessor like this:

class WayCoolObject : public derived4, public MakeACoolObject
{
     ...
}


Then I remove all the special stuff that CoolObjectProcessor needs from CoolObject and put it MakeACoolObject and make CoolObject itself derive from MakeACoolObject.

Then in theory I can do this with no trouble:

code:

CoolObjectProcessor::doCoolProcessorShit()
{
     // CoolObjectProcessor will retrieve CoolObjects like so:
     MakeACoolObject* iAmAssHole = dynamic_cast<MakeACoolObject*> mBaseSet[i];

     // CoolObjectProcessor will call methods on CoolObject like so:
     iAmAssHole->doCoolShit();

    // the result is we have cool shit coming out of our asshole.  Cool as in ice cold. 



Right?
Sponsor
Sponsor
Sponsor
sponsor
md




PostPosted: Fri May 23, 2008 10:36 pm   Post subject: RE:OOP Quandry

I'm not sure I understand your question BUT, it seems like you have a base class (base) and a tree of derived classes (derived1 through derived6); and a final class which is derived from derived6.

Class CoolObjectProcessor takes items of the last derived class (CoolObject), casts them to base, then calls a function on them. What is happening is that the base class's doCoolShit() function is being called, when what you want is CoolObject's doCoolShit() function to be called.

Put simply if it's not a virtual function in base; casting to base will cause the compiler to ignore the vtable. Either CoolObjectProcessor needs to not do any casting (probably the right thing to do) or cast to something that does use vtables (one of hte derived#s I assume).
Geminias




PostPosted: Sat May 24, 2008 1:06 am   Post subject: RE:OOP Quandry

Thanks for taking the time to look over my shitty example md. My problem is that there is something going on that I either don't understand related to C++ or within the mBaseSet which is an object of a container class. My problem, put as succinctly as possible, is this:

c++:

class Base
{
public:
        virtual void sayType()
        {
                cout << "I am a: " << typeid(this).name() << endl;
        }
};

class Derived1 : public Base
{
public:
        void sayType()
        {
                cout << "I am a: " << typeid(this).name() << endl;
        }
};


int main()
{
        TheSet<Base*> baseList;
        baseList.add(new Derived1);

        Base* bPtr = baseList[0];

        bPtr->sayType();   // Outputs that it is a "class Base*"

        // However:

        Derived1 dPtr = dynamic_cast<Derived1>(baseList[0]);
        dPtr->sayType();    // Outputs that it is a "class Derived*"

        return 0;
}


By putting the Derived1 pointer into the TheSet, something is happening to it because it is not calling the Derived1::sayType() despite the Base::sayType() being declared virtual. YET the dynamic_cast operator "fixes" it. I don't understand how it is possible...
wtd




PostPosted: Sat May 24, 2008 2:01 am   Post subject: RE:OOP Quandry

Moderation

Watch the language, please.
DemonWasp




PostPosted: Thu Jun 12, 2008 9:41 pm   Post subject: RE:OOP Quandry

Preface: I'm a noob to C++ too. What I say could easily be misleading, or even dead wrong. That said...

If you ignore the use of TheSet, then you have:

c++:

Derived1* dPtr = new Derived1();
Base* bPtr = dPtr;

bPtr->sayType();
dPtr->sayType();


That functions as expected. So my guess would be that your problem is in TheSet's implementation. I can't imagine how that's even possible, but it may have somehow managed to fool the vtables into thinking it's just a Base*, not a Derived1*.

My advice would be to code up a small, working example, separate from the code you're working on, and see if it exhibits the same behaviour, then you have a basis to work from.
md




PostPosted: Fri Jun 13, 2008 9:53 am   Post subject: RE:OOP Quandry

The problem is that sayType() is not declared as virtual in the base function.
Rigby5




PostPosted: Fri Oct 10, 2008 12:17 am   Post subject: Re: RE:OOP Quandry

Geminias @ Sat May 24, 2008 1:06 am wrote:
Thanks for taking the time to look over my shitty example md. My problem is that there is something going on that I either don't understand related to C++ or within the mBaseSet which is an object of a container class. My problem, put as succinctly as possible, is this:

c++:

class Base
{
public:
        virtual void sayType()
        {
                cout << "I am a: " << typeid(this).name() << endl;
        }
};

class Derived1 : public Base
{
public:
        void sayType()
        {
                cout << "I am a: " << typeid(this).name() << endl;
        }
};


int main()
{
        TheSet<Base*> baseList;
        baseList.add(new Derived1);

        Base* bPtr = baseList[0];

        bPtr->sayType();   // Outputs that it is a "class Base*"

        // However:

        Derived1 dPtr = dynamic_cast<Derived1>(baseList[0]);
        dPtr->sayType();    // Outputs that it is a "class Derived*"

        return 0;
}


By putting the Derived1 pointer into the TheSet, something is happening to it because it is not calling the Derived1::sayType() despite the Base::sayType() being declared virtual. YET the dynamic_cast operator "fixes" it. I don't understand how it is possible...


bPtr is the base class and should call the base function.
When you initialized dPtr to an instance of the base class, that is what you get, a pointer to an instance of the base class.
You should expect it to also then call the base function.
It is only by casting it to the Derived1 class that tells the compiler to make an instance of the Derived1 class.
But is dPtr just a pointer or an actual instance of a different class?
wtd




PostPosted: Fri Oct 10, 2008 12:36 am   Post subject: RE:OOP Quandry

MODERATION

Kind of a necro post.
Sponsor
Sponsor
Sponsor
sponsor
Rigby5




PostPosted: Fri Oct 24, 2008 5:57 pm   Post subject: RE:OOP Quandry

By the way, it really is not considered good form to derive too many layers deep in C++.
I know, Microsoft does is all the time, but in reality one should never go beyond something like 5 layers of inheritance. It makes it too hard to track the .h files unless you have an IDE do it all for you.
wtd




PostPosted: Fri Oct 24, 2008 11:27 pm   Post subject: Re: OOP Quandry

You've been warned about necroposting.
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 10 Posts ]
Jump to:   


Style:  
Search: