Skip to main content
GameDev.net gamedev.net
🔒 Locked

Multiple Inheritance Polymorphism

Started by Makubab May 1, 2012 at 3:27 AM 3 replies 2.6k views
Original Post
Makubab
Makubab
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!
wqking
wqking
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.
wqking
wqking
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;
fastcall22
fastcall22
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.
Makubab
Makubab
Wow, I completely overlooked that fact. Makes a lot of sense, not sure what I was thinking. Thanks for pointing that out!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.