虚继承和虚基类
- 在C++中,在定义公共基类A的派生类B、C…的时候,如果在继承方式前使用关键字virtual对继承方式限定,这样的继承方式就是虚拟继承,公共基类A成为虚基类。这样,在具有公共基类的、使用了虚拟继承方式的多个派生类B、C…的公共派生类D中,该基类A的成员就只有一份拷贝
- 一个类有多个基类,这样的继承关系称为多继承。在多继承的情况下,如果不同基类的成员名称相同,匹配度相同, 则会造成二义性。为了避免多继承产生的二义性,在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。
- 会在虚继承的类中生成一个指向虚基类的指针
{vbptr}
- 会在内存中生成一个虚基类表
D::$vbtable@B@
微软的Visual Studio提供给用户显示C++对象在内存中的布局的选项
cl [filename].cpp /d1 reportSingleClassLayout[className]
一般继承:
class A
{
public:
int dataA;
};
class B:public A
{
public:
int dataB;
};
class C:public A
{
public:
int dataC;
};
class D : public B, public C
{
public:
int dataD;
};
输出:
class D size(20):
+---
0 | +--- (base class B)
0 | | +--- (base class A)
0 | | | dataA
| | +---
4 | | dataB
| +---
8 | +--- (base class C)
8 | | +--- (base class A)
8 | | | dataA
| | +---
12 | | dataC
| +---
16 | dataD
+---
调用:
int main( )
{
D d;
cout << d.dataA << endl;
return 0;
}
调用输出:
Start
prog.cc:29:15: error: non-static member 'dataA' found in multiple base-class subobjects of type 'A':
class D -> class B -> class A
class D -> class C -> class A
cout << d.dataA << endl;
^
prog.cc:9:9: note: member found by ambiguous name lookup
int dataA;
^
1 error generated.
1
Finish
虚继承:
class A
{
public:
int dataA;
};
class B:virtual public A
{
public:
int dataB;
};
class C:virtual public A
{
public:
int dataC;
};
class D : public B, public C
{
public:
int dataD;
};
B
类输出:
class B size(12):
+---
0 | {vbptr}
4 | dataB
+---
+--- (virtual base A)
8 | dataA
+---
B::$vbtable@:
0 | 0
1 | 8 (Bd(B+0)A)
vbi: class offset o.vbptr o.vbte fVtorDisp
A 8 0 4 0
C
类输出:
class C size(12):
+---
0 | {vbptr}
4 | dataC
+---
+--- (virtual base A)
8 | dataA
+---
C::$vbtable@:
0 | 0
1 | 8 (Cd(C+0)A)
vbi: class offset o.vbptr o.vbte fVtorDisp
A 8 0 4 0
D
类输出:
class D size(24):
+---
0 | +--- (base class B)
0 | | {vbptr}
4 | | dataB
| +---
8 | +--- (base class C)
8 | | {vbptr}
12 | | dataC
| +---
16 | dataD
+---
+--- (virtual base A)
20 | dataA
+---
D::$vbtable@B@:
0 | 0
1 | 20 (Dd(B+0)A)
D::$vbtable@C@:
0 | 0
1 | 12 (Dd(C+0)A)
vbi: class offset o.vbptr o.vbte fVtorDisp
A 20 0 4 0