钻石继承与虚基类
当发生钻石继承时,使用虚基类;
B1和B2共同继承B0类,D继承B1和B2类,类似这种继承称为钻石继承;
钻石继承会发生D类继承来自B1和B2共同继承自B0中的成员;
区分方法:
1.子类区分不同父类的相同成员名,可以加上父类的作用域;
2.B1和B2都有BO的拷贝,而D只需要一份,可以让B1和B2虚拟继承B0,这样B1和B2就不会真实的开辟空间,B0的成员也就只有一份;
被虚拟继承的基类被称为虚基类;
把共同的基类设置为虚基类,这样从不同路径继承来的同名数据成员在内存中就只有一个拷贝,同名函数也只有一种映射。
虚基类(virtual base class)定义方式如下:
class 派生类名:virtual 访问限定符 基类类名{...};
class 派生类名:访问限定符 virtual 基类类名{...};
举例:
<span style="font-size:18px;">#include <iostream>
using namespace std;
class B0
{
public:
B0():m(0)
{}
public:
int m;
}
class B1:vitual public B0
{
public:
B1():n(0)
{}
public:
int n;
};
class B2:virtual public B0
{
public:
B2():n(0)
{}
public:
int n;
};
class D : public B1, public B2
{
public:
D():x(0)
{}
private:
int x;
};
int main()
{
D d;
d.n = 10; //错误,n发生二义性,B1和B2都有n
d.B1::n = 10; //正确 1.
d.B1::m = 100; //1.
d.B2::m = 100; //1.
d.m = 100; //2.
return 0;
}</span>
有虚基类的派生类对象的创建中:
1.虚基类的构造函数并按它们声明的顺序构造。
2.非虚基类的构造函数按它们声明的顺序调用。
3.成员对象的构造函数。
4.派生类自己的构造函数被调用