http://blog.csdn.net/bluedog/article/details/4711169
先看下代码:
struct A { A(int v=100):X(v){}; virtual void foo(void){} int X; }; struct B :virtual public A { B(int v=10):Y(v),A(100){}; virtual void fooB(void){} int Y; }; struct C : virtual public A { C(int v=20):Z(v),A(100){} virtual void fooC(void){} int Z; }; struct D : public B, public C { D(int v =40):B(10),C(20),A(100),L(v){} virtual void fooD(void){} int L; }; int _tmain(int argc, _TCHAR* argv[]) { A a; int *ptr; ptr = (int*)&a; cout << ptr << " sizeof = " << sizeof(a) <<endl; for(int i=0;i<sizeof(A)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } cout << "--------------------------------------" <<endl; B b; ptr = (int*)&b; cout <<"addr:" << ptr << " sizeof = " << sizeof(b) <<endl; for(int i=0;i<sizeof(B)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } cout << "--------------------------------------" <<endl; D d; ptr = (int*)&d; cout <<"addr:" << ptr << " sizeof = " << sizeof(d) <<endl; for(int i=0;i<sizeof(D)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } return 0; }
如果B虚拟继承A,则B的对象中要增加一个虚拟基类指针,其指向的表的第二项,即从本指针到虚拟基类的偏移。
例如,对象b,的虚拟基类的地址是120+8 = 128
虚拟基类在b对象的最后。
多重继承,继承n个类,有n个续表指针;包括n个虚基类,有n个虚基类指针。
举个例子,
B虚继承A,如果A中有虚函数,则B类对象的开始位置是虚表指针,第二个位置是虚基类的指针。
class A { public: A():a(1){} int a; }; class B: public virtual A { public: B():b(2){} int b; }; int main() { B* b = new B; A* a = dynamic_cast<A*>(b); if(a == b)//b先默认转为A*,所以相等 { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出equal if (int(b) == int(a)) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出not equal typedef void (*pFun)(void); int **ptb = (int **)b; cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl; cout<<&((int*)ptb)[1]/*<<" "<<ptb[1][1]*/<<endl; cout<<&((int*)ptb)[2]<<endl; cout<<"-------"<<endl; cout<<a<<endl<<b<<endl; }
equal
not equal
0 8
00701E5C
00701E60
-------
00701E60
00701E58
对象b的内存分布是:
虚基类的地址是 58+8 = 60
a为什么不等于b?
a指向了60的地址,而b指向的还是58
如果在虚继承的继承上又有多态重载?
class A { public: virtual void fun1() { cout<<"A"<<endl; } A():a(1){} int a; }; class B: virtual public A { public: B():b(2){} virtual void fun1() { cout<<"B:fun1"<<endl; } virtual void fun2() { cout<<"B:fun2"<<endl; } int b; }; int main() { B* b = new B; A* a = dynamic_cast<A*>(b); if(a == b) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出equal if (int(b) == int(a)) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出not equal cout<<sizeof(B)<<endl; typedef void (*pFun)(void); int **ptb = (int **)b; /* int *ptmp = (int *)b; pFun p = (pFun)((int *)ptmp[0])[0]; p();*/ pFun pfun; pfun =(pFun) ptb[0][0]; // cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl; cout<<"first vtb"<<endl; pfun(); cout<<ptb[1][0]<<" "<<ptb[1][1]<<endl; cout<<((int*)ptb)[2]<<endl;//B:b cout<<(int)ptb[3]<<endl; pfun = (pFun)ptb[4][0]; cout<<"second vtb"<<endl; pfun(); cout<<((int*)ptb)[5]<<endl;//A:a cout<<"-------"<<endl; cout<<a<<endl<<b<<endl; }
output:
equal
not equal
24
first vtb
B:fun2
-4 12
2
0
second vtb
B:fun1
1
-------
00360A18
00360A08
08 vftable ---->B:fun2()
0c base_psb---->-4,12
10 B:b
14 0//不知道为什么为0?
18 vftable------>B:fun1()
1c A:a
如果B类变为
class B: virtual public A
{
public:
B():b(2){}
virtual void fun1()
{
cout<<"B:fun1"<<endl;
}
void fun2()
{
cout<<"B:fun2"<<endl;
}
int b;
};
fun2不是虚函数,所以对象b的开始不是虚函数表指针,而是虚基类指针
pFun pfun;
cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl;
cout<<((int*)ptb)[1]<<endl;//B:b
pfun =(pFun) ptb[3][0];
pfun();
/*cout<<(int)ptb[3]<<endl;
pfun = (pFun)ptb[4][0];
cout<<"second vtb"<<endl;
pfun();*/
cout<<((int*)ptb)[4]<<endl;//A:a
cout<<"-------"<<endl;
cout<<a<<endl<<b<<endl;
output:
equal
not equal
20
0 12
2
B:fun1
1
-------
004D3DB4
004D3DA8
同样,为什么第2项为0?