http://blog.youkuaiyun.com/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;
}
output:
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?