如果一个派生类从多个基类派生, 而这些基类又有一个共同的基类, 则在对该基类中声明的名字进行访问时, 可能产生二义性。
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/d750f1784d643f5e8e8b1acda90c1a27.png)
创建D类的对象时, B的构造函数将会被调用两次, 一次由C1的构造函数调用, 一次由C2的构造函数调用。 这样C类的对象中就会包含2个B类的子对象。
通过D类对象访问B类成员时, 会出错:
D d; //定义一个D类对象d
//d.b_ = 1; //出错, 对b_的访问不明确
d.C1::b_ = 1; //正确, 从C1继承而来的b_
d.C2::b_ = 3; //正确, 从C2继承而来的b_
要使公共基类B在派生类D中只产生一个子对象, 必须将这个基类B声明为虚继承, 使这个基类成为虚基类。
虚继承的声明:
class C1: virtual public B
{}c
lass C2: virtual public B
{}
#include<iostream>
using namespace std;
class B
{
public:
int b_;
B(int b = 0)
{
b_ = b;
cout << "调用B的构造函数" << endl;
}
};
class C1 :virtual public B
{
public:
int c1_;
C1(int b = 0, int c1 = 0) : B(b)
{
c1_ = c1;
cout << "调用C1的构造函数" << endl;
}
};
class C2 : virtual public B
{
public:
int c2_;
C2(int b = 0, int c2 = 0) : B(b)
{
c2_ = c2;
cout << "调用C2的构造函数" << endl;
}
};
class D : public C1, public C2
{
public:
int d_;
D(int b = 0, int c1 = 0, int c2 = 0, int d = 0) :B(b), C1(b, c1), C2(b, c2)
{
d_ = d;
cout << "调用D的构造函数" << endl;
}
void print()
{
cout << "b_: " << b_ << " c1_: " << c1_ << " c2_: " << c2_ << " d_: " << d_ << endl;
}
};
int main()
{
D d1(2, 3, 4, 5);
d1.print();
d1.b_ = 5; //不加virtual,会出错,值不明确
//d1.C1::b_ = 6;
//d1.C2::b_ = 9;
d1.c1_ = 10;
d1.c2_ = 5;
d1.d_ = 8;
d1.print();
return 0;
}