C++ 使用Virtual关键字的多重继承中的菱形继承

C++ 使用Virtual关键字的多重继承中的菱形继承,c++,C++,我听说使用虚拟关键词可以解决钻石问题 然而,当我这样做时: #include <iostream> using namespace std; class A { public: A(int x = 100) { num = x; } protected: int num; }; class B1 : virtual public A{ public: B1(int x = 50) : A(2*x) { } }; clas

我听说使用虚拟关键词可以解决钻石问题

然而,当我这样做时:

#include <iostream>

using namespace std;

class A {
public:
    A(int x = 100) {
        num = x;
    }
protected:
    int num;
}; 

class B1 : virtual public A{
public:
    B1(int x = 50) : A(2*x) {
    }
};
class B2 : virtual public A{
public:
    B2(int x = 50) : A(2*x) {
    }
};
class C : public B1, public B2 {
public:
    C(int x = 75) : B1(2*x), B2(2*x) {};
    int getData(){ return num; } 
};

int main() {
    C c(10);

    cout << c.getData(); 
    cin.get();
    return 0;
}
#包括
使用名称空间std;
甲级{
公众:
A(整数x=100){
num=x;
}
受保护的:
int-num;
}; 
B1类:虚拟公共A{
公众:
B1(整数x=50):A(2*x){
}
};
B2类:虚拟公共A{
公众:
B2(整数x=50):A(2*x){
}
};
C类:公共B1、公共B2{
公众:
C(intx=75):B1(2*x),B2(2*x){};
int getData(){return num;}
};
int main(){
C(10);

cout当您使用虚拟继承时,您保证有一个公共基类()的实例;因此,
B1
B2
不能有自己的
A
实例,但它们将与
C
共享一个实例。例如,如果您定义
C
的构造函数如下:

C(int x = 75) : B1(2*x), B2(2*x), A(x) {};
您将看到您的代码输出
10
。关键在于@dyp的注释:

公共基类在最派生的类中初始化


(当然,在上面的示例中,在初始值设定项列表中包含所有
B1
B2
A
是没有任何意义的,因为拥有
A
就足够了)。

虚拟基类是在最派生的类(您创建的实际对象的类型)中初始化的。由于
C
中没有
A
的初始值设定项,
A
的构造函数的参数默认为100。或者任何基类?很抱歉,我不明白您指的是什么。一个类初始化其所有非虚拟直接基类(如果它是最派生的类型,还初始化其所有虚拟基类)也就是说,如果
B
非虚拟地继承自
A
,则
B
初始化其
A
基类子对象。如果
C
继承自
B
,则
C
不会初始化
B
A
基类子对象。@Barry我宁愿使用我的Mjölnir。除了它太重,我也不喜欢它“我有点累了;)呜呜呜呜呜呜!!!!!!!!!!!!!!!!!!!!!!!!!!!!!是的!!!谢谢。我现在掌握了这个概念!