Multiple Inheritance Polymorphism

Started by
3 comments, last by Makubab 11 years, 11 months ago
Hello,

I came across an issue with multiple inheritance and polymorphism and isolated it down to the following code:


class class0
{
public:
virtual void test0(void);
};
class Class1
{
public:
virtual void test1(void);
virtual void test2(void);
};
class Class2 : public Class1, public class0
{
public:
virtual void test1(void);
virtual void test2(void);
virtual void test0(void);
};
void Class2::test0(void)
{
}
void class0::test0(void)
{
}
void Class1::test1(void)
{
}
void Class1::test2(void)
{
}
void Class2::test1(void)
{
}
void Class2::test2(void)
{
}
int main(void)
{
Class1* c1 = new Class2[10];
// Works
((Class2*)c1)[1].test1();
((Class2*)c1)[1].test2();

// Does not work.
c1[1].test1();
c1[1].test2();
delete[] c1;
}


Now, it seems to me that under polymorphism, both those cases should work. When I investigate c1's virtual function table, it changes at each index. Various testing has shown me the virtual function table ranges from being just plain wrong to not showing up per item correctly. For example it will show only Class1's table for c1[0], and only class0's table for c1[1]. The code that does not work will crash due to an Access Violation. This is with Visual Studio 2010, default compiler.

Maybe I am doing something wrong, this just looks like a bug though. It seems to effectively kill the ability to do polymorphism with multiple inheritance. Any explanation on what's happening here or if I am missing something important would be appreciated.

Thanks!
Advertisement
The problem is
Class1* c1 = new Class2[10];

C1 points to an VALUE array of class2, but note Class1 and Class2 have different size.
So C1[1] won't point to correct Class2, it points to invalid memory.

You should not assign "new Class2[10]" to Class1 pointer. You need to assign to Class2 pointer.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

Plus, polymorphism is obtained via pointer or reference, not via value.
So to get polymorphism, you need to allocate for pointers.
Pseudo code,

Class1 ** c1 = new Class1 * [10];
for(loop 10) C1 = new Class2;

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

And, unless you want two instances of class0 (Class1::class0 and Class2::class0), you'll need virtual inheritance to solve the dreaded diamond inheritance problem.
Wow, I completely overlooked that fact. Makes a lot of sense, not sure what I was thinking. Thanks for pointing that out!

This topic is closed to new replies.

Advertisement