- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我了解并阅读了足够多的有关虚拟继承解决的菱形问题。我的问题是
"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/
Feel free to skip straight to TL/DR if you're not interested in details of the question 简短的序言: 我最近决定
我一直在阅读 A Tour of Go学习Go-Lang到目前为止一切顺利。 我目前在 Struct Fields类(class),这是右侧的示例代码: package main import "fm
Last time I got confused顺便说一下PowerShell急切地展开集合,基思总结了它的启发式如下: Putting the results (an array) within a
我是一名优秀的程序员,十分优秀!