class Base1 {
virtual void fun1() { cout << "Base1::fun1()" << endl; }
virtual void func1() { cout << "Base1::func1()" << endl; }
};
class Base2 {
virtual void fun1() { cout << "Base2::fun1()" << endl; }
virtual void func1() { cout << "Base2::func1()" << endl; }
};
class Test:public Base1,public Base2
{
public:
virtual void test(){cout<<"Test";}
};
typedef void(*Fun)(void);
int main()
{
Test objTest;
Fun pFun = NULL;
pFun = (Fun)*((int*)*(int*)((int*)&objTest+0)+0); pFun();
pFun = (Fun)*((int*)*(int*)((int*)&objTest+0)+1); pFun();
//The following isnt supposed to print Test::test() right?
pFun = (Fun)*((int*)*(int*)((int*)&objTest+0)+2); pFun();
pFun = (Fun)*((int*)*(int*)((int*)&objTest+1)+0); pFun();
pFun = (Fun)*((int*)*(int*)((int*)&objTest+1)+1); pFun();
//Isnt the following supposed to print Test:test() because the order of
construction object is Base1 followed by construction of Base2 followed by
construction of Test.
pFun = (Fun)*((int*)*(int*)((int*)&objTest+1)+2); pFun();
}
The sizeof Test object is 8 bytes.
So it is evident from this example that the object consists of two 4 byte _vptr's. Since the order of inheritance is public Base1,public Base2
that means the object should be made in the following way:
| _vptr to class Base1 vTable | -->this Base1 vtable should have 2 elements.
| _vptr to class Base2 vTable | -->this Base2 vtable should have 3 elements.
But from the code snippet it looks like the object is made as:
| _vptr to class Base1 vTable | -->this Base1 vtable should have 3 elements.
| _vptr to class Base2 vTable | -->this Base2 vtable should have 2 elements.
The first vptr points an array of 3 function pointers(1st points Base1::fun1()
, 2nd points to Base1::func1()
and third points to Test::test()
).
A derived object is made up of Base+Derived. That means first chunk of bytes is Base object and the remaining is Derived.
If so, then in our example of objTest , the second _vptr
should be supposed to point to three function pointers (1st to Base2::fun1()
, Base2::func1()
and Test::test()
). But we see instead that the first _vptr
points to function pointer of Test::test()
.
Question:
1. Is this behavior compiler specific ?
2. Does the standard mention anything about this behavior? Or my understanding is wrong completely?