c++ - C++菱形继承(钻石问题)中如何调用所有基类的拷贝构造函数来拷贝大部分派(dispatch)生类对象?

标签 c++ copy-constructor virtual-inheritance ctor-initializer private-inheritance

考虑下面的代码:

#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 的拷贝构造函数, BCD 的复制构造函数时被调用。这可能是非常小的变化,但我没有得到。

最佳答案

首先,让我们更改您的继承,因为它目前是私有(private)的:

class B : virtual protected A {...};
class C : virtual protected A {...};

现在,在你的复制构造函数中,显式指定 AB 以及 C 的复制构造函数应该被调用:

class D : protected B, protected C {
    D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
};

并且输出将是所需的 (2468)。

为什么?

当我们有虚拟基类时,它们必须由最派生的类初始化,否则会出现BC的歧义> 例如负责构造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/

相关文章:

c++ - vector::clear 如何在不丢失已分配内存的情况下调用析构函数

c++ - 为什么这行不通(C++ 函数原型(prototype))

c++ - 如何在创建复制构造函数时正确重载 operator=

c++ - 从具有虚函数的多个继承类派生的类的大小

c++ - 链接器错误 : undefined symbol

c++ - 对象指针和超出范围的对象的 vector

C++,如何在复制构造函数中正确复制 std::vector<Class *>?

c++ - 用于多个虚拟继承和类型转换的虚拟表和虚拟指针

c++ - 什么是多重虚拟继承?

c++堆栈和堆上的多维数组布局