gpt4 book ai didi

c++ - 为什么这个菱形类继承输出不是我期望的?

转载 作者:可可西里 更新时间:2023-11-01 14:54:06 26 4
gpt4 key购买 nike

考虑:

#include <iostream>

using namespace std;

class A {// base class
private:
int data;
public:
A(int data = 0)
{
this->data = data;
}
void show()
{
cout << data << endl;
return;
}
};

class B : virtual public A {
public:
B(int data = 0) :
A(data) {
}
};

class C : virtual public A {
public:
C(int data = 0) :
A(data) {
}
};

class D : public B, public C {
public:
D(int dataB = 0, int dataC = 0) :
B(dataB),
C(dataC) {
}
};

int main() {
D d(1, 2);
d.B::show();
d.C::show();
return 0;
}

上面的代码就是diamond类的继承图。基类是A。我使用虚拟继承来避免菱形问题。但为什么这个程序的输出是0,0,而不是我预期的1,2

B 的构造函数被传递给 data=1,并且在它的初始化列表中它调用 Adata >。 C 的构造函数类似传递 data=2 及其初始化列表,它调用 Adata

然后我们要求 BC 子对象显示它们的值。我们得到的是 0 0 而不是我预期的 1 2

最佳答案

当你有这个带有虚拟继承的方案时,层次结构中最派生的类(在本例中为D)调用公共(public)基类(A)1,2.

因为A 的构造函数有一个默认参数data = 0,它可以用作默认构造函数。这就是正在发生的事情,公共(public) A 子对象默认构造,因为您从 D 的成员初始化列表中省略了它。

如果您删除 data 的默认值,您将得到一个很好的编译器错误以强调:

A(int data) 
{
this->data = data;
}

On g++ it results with :

main.cpp: In constructor 'D::D(int, int)':
main.cpp:37:16: error: no matching function for call to 'A::A()'
C(dataC) {

1 请记住,对于虚拟继承,只有 一个 类型为 A 的子对象。 BC 子对象都引用它。您对 show 的调用不可能打印不同的内容,因为它们访问相同 数据。这就是为什么它取决于最派生的类,所以没有歧义。

[class.mi/4]

A base class specifier that does not contain the keyword virtual specifies a non-virtual base class. A base class specifier that contains the keyword virtual specifies a virtual base class. For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object shall contain a corresponding distinct base class subobject of that type. For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.

[class.base.init/13.1]

In a non-delegating constructor, initialization proceeds in the following order:

  • First, and only for the constructor of the most derived class, 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.

  • ...

2 因此,如果您想使用特定数据构造 A,您可以像这样定义 D::D():

D(int dataA = 0) :
A(dataA) {
}

关于c++ - 为什么这个菱形类继承输出不是我期望的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43581170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com