考虑下面的代码:
#include<iostream>
using namespace std;
class A
{
public:
A() {cout << "1";}
A(const A &obj) {cout << "2";}
};
class B: virtual A
{
public:
B() {cout << "3";}
B(const B & obj) {cout<< "4";}
};
class C: virtual A
{
public:
C() {cout << "5";}
C(const C & obj) {cout << "6";}
};
class D:B,C
{
public:
D() {cout << "7";}
D(const D & obj) {cout << "8";}
};
int main()
{
D d1;
cout << "\n";
D d(d1);
}
程序的输出如下:
1357
1358
因此,对于行 D d(d1)
D
的拷贝构造函数正在调用类。在继承过程中,我们需要显式调用基类的复制构造函数,否则只会调用基类的默认构造函数。到这里我才明白。
我的问题:
现在我想在 D d(d1)
期间调用所有基类的复制构造函数执行。为此,如果我在下面尝试
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
然后我得到这个错误:
错误:'class A A::A' is inaccessible within this context
如何解决这个问题。我想要 A
的拷贝构造函数, B
和 C
当 D
的复制构造函数时被调用。这可能是非常小的变化,但我没有得到。
最佳答案
首先,让我们更改您的继承,因为它目前是私有(private)的:
class B : virtual protected A {...};
class C : virtual protected A {...};
现在,在你的复制构造函数中,显式指定 A
和 B
以及 C
的复制构造函数应该被调用:
class D : protected B, protected C {
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
};
并且输出将是所需的 (2468
)。
为什么?
当我们有虚拟基类时,它们必须由最派生的类初始化,否则会出现B
或C
的歧义> 例如负责构造A
。
§12.6.2, (13.1):
In a non-delegating constructor, initialization proceeds in the following order:
- First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
特别是,如果您定义了一个复制构造函数,并省略了它应该调用的复制构造函数列表,那么将使用默认构造函数。
关于c++ - C++菱形继承(钻石问题)中如何调用所有基类的拷贝构造函数来拷贝大部分派(dispatch)生类对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43703229/