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();
}
测试对象的大小为 8 个字节。所以从这个例子中可以明显看出,该对象由两个 4 字节的 _vptr 组成。由于继承的顺序是public Base1,public Base2
这意味着对象应该以下列方式制作:
| _vptr to class Base1 vTable | -->this Base1 vtable should have 2 elements.
| _vptr to class Base2 vTable | -->this Base2 vtable should have 3 elements.
但从代码片段看来,该对象是这样制作的:
| _vptr to class Base1 vTable | -->this Base1 vtable should have 3 elements.
| _vptr to class Base2 vTable | -->this Base2 vtable should have 2 elements.
第一个 vptr 指向一个由 3 个函数指针组成的数组(第一个指向Base1::fun1()
,第二个指向Base1::func1()
,第三个指向Test::test()
)。
派生对象由 Base+Derived 组成。这意味着第一个字节块是 Base 对象,其余的是 Derived。如果是这样,那么在我们的 objTest 示例中,第二个应该_vptr
指向三个函数指针(第一个指向Base2::fun1()
和)。但是我们看到 first指向 的函数指针。Base2::func1()
Test::test()
_vptr
Test::test()
问题:
1.这种行为编译器是特定的吗?
2.标准是否提到了这种行为?还是我的理解完全错误?