c++ - 具有虚拟多重继承的构造函数定义

标签 c++ inheritance multiple-inheritance

<分区>

我认为一个例子可以最好地描述我的问题。

struct Base {
    Base() = delete;
    Base(int x) : x(x) {}
    int x;
};

struct Derived1 :  virtual Base {
    Derived1(int y) : Base(5), y(y) {}
    int y;
};

struct Derived2 :  virtual Base {
    Derived2(int z) : Base(10), z(z) {}
    int z;
};

struct Derived3: Derived1, Derived2 {
public:
    Derived3(int y, int z) : Derived1(y), Derived2(z) {}

};

我得到一个错误: 在构造函数“Derived3::Derived3(int, int)”中: 错误:使用已删除的函数“Base::Base()” Derived3(int y, int z) : Derived1(y), Derived2(z) {}

我不明白为什么会出现这个错误。在我看来,在这个例子中,所有基类实际上都是通过它们的构造函数初始化的(显式 Derived1Derived2 以及通过 Derived2 隐式地 Base (我在这里不确定,也许通过 Derived1))。 好吧,让我们按照编译器告诉我的去做。

struct Derived3: Derived1, Derived2 {
public:
    Derived3(int y, int z) : Base(-1), Derived1(y), Derived2(z) {}

};

它会编译,如果我现在这样做:

Derived3 d = Derived3(7, 9);
std::cout << d.x << std::endl;
std::cout << d.y << std::endl;
std::cout << d.z << std::endl;

我得到 -1, 7, 9。这根本不是我想要的。一个想法是用它的一个派生类来初始化基类,我期望第一个数字是 5 或 10。

所以,这是我的问题: 为什么我在派生类之一中已经完成时被迫显式调用 Base 构造函数?

更具体地说,由于我有多重继承和虚拟继承,我相信 Derived3 的任何实例都恰好有一个 Base 类实例的拷贝。我期待 Base 的这个拷贝在它的最派生类(Derived1Derived2)中初始化,但我清楚地可以看到它不能以这种方式工作=(我哪里错了?

最佳答案

当你使用虚继承时,只有一份Base。谁应该初始化该拷贝,Derived 1 或 Derived 2?没有办法知道。这就是为什么您被迫在 Derived 3 中自己做,所以不会有歧义。这也是为什么您得到的输出不是 5 或 10。

如果没有虚拟继承,Derived 1 和 Derived 2 都将拥有自己负责的 Base 拷贝,因此没有歧义。当您强制它们从同一个基继承时,Derived 3 必须取得 Base 的所有权才能解决歧义......虚拟继承充其量是奇怪的。

关于c++ - 具有虚拟多重继承的构造函数定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770202/

相关文章:

Python方法解析顺序

python - 定义您自己的 python 对象和数据类型

iphone - 在 openGL ES1 中为 iphone 绘制立方体

.net - 一个接口(interface)是否应该继承另一个接口(interface)

c++ - 是否有一种 C++20 方法可以仅使用概念和 requires() 来检测类型是否是模板的实例化?

c# - 接口(interface)疑惑问题

c# - 为什么仅在实现接口(interface)后才重写方法?

python - python中的多重继承与 super

c++ - 如何检查堆栈是否未损坏

c++ - 调用函数时栈上有什么?