gpt4 book ai didi

c++ - 在 C++ 的菱形问题中,为什么我们需要从子类调用 grand_parent 构造函数?

转载 作者:可可西里 更新时间:2023-11-01 14:57:29 30 4
gpt4 key购买 nike

请阅读代码了解情况。

#include <iostream>
using namespace std;
class one
{
protected:
int x;
public:
one(int a)
{
x=a;
cout << "one cons called\n";
}
void display(void)
{
cout << "x = " << x << endl;
}
~one()
{
cout << "one destroy\n";
}
};
class two : virtual protected one
{
protected:
int y;
public:
two(int a,int b) : one(a),y(b)
{
cout << "two cons called\n";
}
void display(void)
{
one::display();
cout << "y = " << y << endl;
}
~two()
{
cout << "two destroy\n";
}
};

class three : protected virtual one
{
protected:
int z;
public:
three(int a,int b) : one(a),z(b)
{
cout << "Three cons called\n";
}
void display(void)
{
one::display();
cout << "z = " << z << endl;
}
~three()
{
cout << "three destroy\n";
}
};

class four : private two, private three
{
public:
four(int a,int b,int c) :one(a), two(a,b),three(a,c)
{
cout << " four cons called\n";
}
void display(void)
{
one::display();
cout << "y = " << y << endl;
cout << "z = " << z << endl;
}
~four()
{
cout << "four destroy\n";
}
};
int main()
{
four ob(1,2,3);
ob.display();
return 0;
}

如果我替换代码

four(int a,int b,int c) :one(a), two(a,b),three(a,c)

four(int a,int b,int c) :two(a,b),three(a,c)

一个错误消息,例如:在我的代码块 ide 中没有匹配函数调用 'one::one()'。

如您所见,这是一个基于菱形问题的代码。其中第一个类是祖父类。二、三类为父类,四类为子类。所以我使用了 virtual 关键字来避免歧义。我在这里理解的一切,除非一件事。我知道当父类具有参数化构造函数时,我们需要从派生类向该构造函数提供参数。那么为什么需要向构造函数 1 提供参数,其中类 4 只有 2 个父类,即 2 和 3。如果我不从第四类调用构造函数一,代码将给我编译时错误。请解释为什么我们需要这样做。

最佳答案

层次结构中的 virtual 继承通过确保仅存储 one 的一个实例来消除基类 one 的存在歧义在 twothree 的子类中。回想一下,当继承某个类时,派生实例将始终在内部某处存储基实例 - 因此 virtual 继承确保 one 的实例在 twothree 在某种程度上被继承层次结构下方的任何类“覆盖”。

现在的问题是:谁负责初始化这个单独的 one 实例?应该是 two 还是 three?显然不是他们两个,因为只有一个例子。你在这里:它始终是最派生的类负责初始化one - 这是有道理的:嵌入基类拷贝的实例必须对其进行初始化。

这是没有 four 和有 four 加上 virtual 继承的带有嵌入式基类实例的类层次结构:

              +----------+                           +----------+
| one | | one |
+----+-----+ +----+-----+
| |
| |
+-------+-----------+ virtual +--------+--------+ virtual
| | | |
| | | |
+--------+-------+ +-------+-------+ +----+----+ +----+----+
| two | | three | | two | | three |
| +------------+ | | +----------+ | +----+----+ +----+----+
| | one | | | | one | | | |
| +------------+ | | +----------+ | +--------+--------+
| => must init! | | => must init! | |
+----------------+ +---------------+ +-------+--------+
| four |
| +------------+ |
| | one | |
| +------------+ |
| => must init! |
+----------------+

你可以这样想这个机制:virtual 继承赋予基类实例 virtual-ness,这包括构建实例 - 这种责任被传递给层次结构。

关于c++ - 在 C++ 的菱形问题中,为什么我们需要从子类调用 grand_parent 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57214656/

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