Jump to content
  • Advertisement
Sign in to follow this  
Gumgo

C++ multiple inheritance

This topic is 3031 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using multiple inheritance for some stuff, and I'm wondering if anyone could explain how it is generally implemented. I don't quite get how some things are possible. Suppose I have the following:
class BaseA {
public:
	int a;
};

class BaseB {
public:
	int b;
};

class DerivedAB : public BaseA, public BaseB {
public:
	void setAB() {
		a = 10;
		b = 20;
	}
};

First of all, in memory, what is the layout of DerivedAB? Is it BaseA followed by BaseB? I did the following test:
DerivedAB * derived = new DerivedAB();
derived->setAB();

BaseA * aPtr = derived;
BaseB * bPtr = derived;

std::cout << "Value of a from aPtr: " << aPtr->a << '\n';
std::cout << "Value of b from bPtr: " << bPtr->b << '\n';
std::cout << "Location of derived: " << derived << '\n';
std::cout << "Location of aPtr: " << aPtr << '\n';
std::cout << "Location of bPtr: " << bPtr << '\n';

DerivedAB * derivedPtr = (DerivedAB*)bPtr;
std::cout << "Value of b from derivedPtr: " << derivedPtr->b << '\n';

delete bPtr;

I create a new DerivedAB and then point to it from a pointer of each base class. The output I get (which is expected) is as follows:
Value of a from aPtr: 10
Value of b from bPtr: 20
Location of derived: 00035F98
Location of aPtr: 00035F98
Location of bPtr: 00035F9C
Value of b from derivedPtr: 20
When (implicitly) casting from DerivedAB* to BaseB*, the location of bPtr was offset by 4 from the location of derived. How does delete work with this? In my test, I new a DerivedAB and I delete a BaseB. How is it determined that the object I should be deleting is actually 4 memory locations back? Basically, some info on how this is implemented would be useful because I don't want to mess something up because I don't understand it. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
delete bPtr;
Ignoring multiple inheritance, this is already doing the wrong thing. If you want to be able to delete derived types from base pointers, then the base needs to have a virtual destructor.
e.g.
class BaseB {
public:
virtual ~BaseB() {}
int b;
};
These links should help:
[11] Destructors
[20.7] When should my destructor be virtual?
[25] Inheritance — multiple and virtual inheritance

Share this post


Link to post
Share on other sites
The memory layout for non-POD types is not defined in the standard. Then again, unless you are doing something really strange there is no reason your code should depend on the memory layout.

It is enough to say that the compiler should have a consistent model and that it will figure out how to do the correct thing in all situations required of it. As long as your code doesn't invoke undefined behaviour (such as deleting a type without using the correct compile type time, when such a type lacks a virtual destructor).

Now, for some more practical information. Typically, mutliple inheritance is implemented by having each object sequentially added to the last in memory, possibly with padding. Each object may have mutliple vtable pointers (again, assuming the most common implementation of dynamic dispatch). A pointer to a superclass will typically point to the offset in the derived class. This is one of the reasons why reinterpret_cast<> is dangerous, it will not take such offsets into consideration. I would strongly recommend using static_cast or dynamic_cast rather than C style casts.

Finally, inheritance is often overused where composition could be used instead. There are alternatives to multiple inheritance, and you should strongly consider them before taking the more complex solution.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!