
-----------------------------------
Geminias
Fri May 23, 2008 6:20 pm

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:  


CoolObjectProcessor::doCoolProcessorShit()
{
     // CoolObjectProcessor will retrieve CoolObjects like so:
     CoolObject* iAmAssHole = dynamic_cast 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: 


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: 


CoolObjectProcessor::doCoolProcessorShit()
{
     // CoolObjectProcessor will retrieve CoolObjects like so:
     MakeACoolObject* iAmAssHole = dynamic_cast 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?

-----------------------------------
md
Fri May 23, 2008 10:36 pm

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
Sat May 24, 2008 1:06 am

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:  


class Base
{
public:
	virtual void sayType()
	{
		cout 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
Fri Jun 13, 2008 9:53 am

RE:OOP Quandry
-----------------------------------
The problem is that sayType() is not declared as virtual in the base function.

-----------------------------------
Rigby5
Fri Oct 10, 2008 12:17 am

Re: 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:  


class Base
{
public:
	virtual void sayType()
	{
		cout 