gpt4 book ai didi

c++ - 虚拟继承 - 菱形继承(钻石问题) - 究竟发生了什么

转载 作者:行者123 更新时间:2023-11-28 06:58:42 25 4
gpt4 key购买 nike

我了解并阅读了足够多的有关虚拟继承解决的菱形问题。我的问题是

"What does placing virtual next to a base class that you would be inheriting from actually mean"

class A { public: void Foo() {} };
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};

我想知道我的理解是否正确。在声明中

  class D : public B, public C {}

编译器将首先检查基类 B 并注意到它实际上继承自 class A。编译器将检查类 A 的实例是否存在,如果不存在,它将创建一个由 B 派生的 A 实例。然后编译器将遍历 C 类并注意到它实际上继承自 A 类。但是由于它实际上被 C 继承并且 A 的实例已经存在,因此它不会包含新实例。从而解决菱形继承(钻石问题)。这种理解是否正确?

最佳答案

是的,您的理解是正确的,但很难说出虚拟继承真正合理的场景,即使在这些情况下,问题通常也可以用其他更简单的方法解决。

在您的情况下,您的 D 实例将由 C、B 和单个 A 实例组成。由于 A 和 B 都可以参与具有不同组合的不同场景,其中 A 实际上被许多类(可能比 A 和 B 更多的类)继承,因此不清楚如何布置例如 D 实例的构建 block 内存。出于这个原因,为 B 类和 C 类编译的代码通常使用实用程序指针或偏移量(每个实例 1 个指针,一个用于 B,一个用于 C)指向由继承的不同类的代码共享的 A 实例实际上来自 A 类。这会占用您的 D 实例中的额外空间,并通过使用这些指针来降低您的代码的效率。

另一个丑陋的实现细节是,在您的 D 类的情况下,当您创建/初始化 D 的实例时,您的 B 和 C 实例都在“竞相”从它们的构造函数中调用类 A 的构造函数。出于这个原因,您的 D 实例还将包含一个 bool 变量,该变量指示是否有人已经从其构造函数中调用了 A 的构造函数。 B 和 C 的 ctors 之一将获胜并将此 bool 变量设置为真,因此来自其他“虚拟后代”的 ctors 的以下尝试在检查该特定 bool 值后简单地退出。

虚拟继承非常丑陋,应尽可能避免。

关于c++ - 虚拟继承 - 菱形继承(钻石问题) - 究竟发生了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22820707/

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