3

据我所知,virtual 确保只有一个基类属性的副本被继承到派生类。在多重继承中,首先调用所有基类的构造函数,然后调用派生类的构造函数。在下面的代码中,为什么 B 类的构造函数连续调用了两次?据我了解,输出应该是

B
B1
B2
D

但输出结果是

B
B
B1
B2
D

这是完整的代码。

#include <iostream>

class B
{
public:
    B(){std::cout << "B" << std::endl;}
};

class B1:public B
{
public:
    B1(){std::cout << "B1" << std::endl;}
};

class B2:virtual public B
{
public:
    B2(){std::cout << "B2" << std::endl;}
};

class D:public B1, public B2
{
public:
    D(){std::cout << "D" << std::endl;}
};

int main()
{
    D d1;
}
4

3 回答 3

5

B1 对 B 的继承也必须是虚拟的。

虚拟继承并不意味着“在层次结构的其余部分中查找该类的继承实例”,而是意味着“对该层次结构中的所有虚拟继承仅使用一个继承实例”。

于 2021-09-13T12:13:41.643 回答
1

这是经典的“钻石问题”(在此处描述)。您对virtual关键字的理解是正确的,但它仅适用于同时用于B1和的情况B2

于 2021-09-13T12:15:41.047 回答
-1

像这样编写代码:

#include <iostream>

class B
{
public:
    B(){std::cout << "B" << std::endl;}
};

class B1:public B
{
public:
    B1(){std::cout << "B1" << std::endl;}
};

class B2:public B1
{
public:
    B2(){std::cout << "B2" << std::endl;}
};

class D:public B2
{
public:
    D(){std::cout << "D" << std::endl;}
};

int main()
{
    D d1;
}
于 2021-09-14T10:36:01.253 回答