- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是对一些真实代码的简化,当我没有意识到其他人已经实现了 Foo 并从中派生时,我犯了一个真正的错误。
#include <iostream>
struct Base {
virtual ~Base() { }
virtual void print() = 0;
};
struct OtherBase {
virtual ~OtherBase() { }
};
struct Foo : public Base { // better to use virtual inheritance?
virtual void print() { std::cout << "Foo" << std::endl; };
};
struct Bar : public Base { // better to use virtual inheritance?
virtual void print() { std::cout << "Bar" << std::endl; };
};
// The design is only supposed to implement Base once, but I
// accidentally created a diamond when I inherited from Bar also.
class Derived
: public OtherBase
, public Foo
, public Bar // oops.
{
};
int main() {
Derived d;
OtherBase *pO = &d;
// cross-casting
if (Base *pBase = dynamic_cast<Base *>(pO))
pBase->print();
else
std::cout << "fail" << std::endl;
}
编辑:让您不必运行此代码...
对于虚拟继承,结果要么是好的,要么是编译器错误。如果没有虚拟继承,结果要么是好的,要么是无法解释的、难以调试的运行时故障。
当我实现 Bar 时,它基本上复制了 Foo 已经在做的事情,它导致动态转换失败,这在实际代码中意味着不好的事情。
起初我很惊讶没有编译器错误。然后我意识到没有虚拟继承,这会在 GCC 中触发“没有唯一的最终覆盖程序”错误。我故意选择不使用虚拟继承,因为在这个设计中不应该有任何菱形。
但是,如果我在从 Base 派生时使用了虚拟继承,那么代码将同样有效(没有我的糟糕),并且我会在编译时收到钻石警告,而不必在运行时追踪错误时间。
所以问题是——您认为使用虚拟继承来防止将来犯类似错误是否可以接受?在这里使用虚拟继承没有充分的技术理由(我可以看到),因为设计中永远不应该有菱形。它只会在那里强制执行该设计约束。
最佳答案
这不是个好主意。
虚拟继承只有在事先计划好的情况下才会使用。正如您刚刚发现的,在许多情况下,所有后代类都必须知道它。如果基类有一个非默认构造函数,您必须担心它总是由叶类构造的事实。
哦,除非自从我上次查看以来情况发生了变化,否则在没有基类帮助的情况下,您不能将虚拟基类向下转换为任何派生类。
关于c++ - 可以接受使用虚拟继承来防止意外创建钻石吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1402384/
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我有几个 div,我想将它们旋转成菱形,但我不希望它们的背景图像旋转,我该如何实现?这是我现在的代码 dj-1-overlay.png" /> 和我的 CSS: #diamonds div { -
我正在制作 Canvas 动画,其中一个图像应该是钻石。 现在,我做到了这一点: ctx[0].beginPath(); ctx[0].moveTo(0,-80); ctx[0].lineTo(-60
考虑以下几点: #include #include using namespace std; class A { public: A(const char* sName) //convers
以某种方式检测 charuco 钻石对我来说不适用于更大的图像。使用我的 1920x1080 原始图像,它既不能可靠地识别 id(菱形 id 元素每次都在切换位置)。在第一张图片中,您可以看到它识别出
下面的代码是关于菱形继承(钻石问题)的。虚拟继承解决了这种歧义。 #include using namespace std; class A { public: voi
我目前正在开发 2D 等距 map 编辑器。我显示包含点和纹理的实体(立方体,播放器)。每个立方体由12个点组成。(12个点,但在sfml(sf::VertexArray)显示时作为4个点的3条边处理
如何在 iOS 的 openframeworks 中构建 3d 钻石?我很难在 openframeworks 中找到有用的 3d 渲染教程,我来自 Processing。 最佳答案 我认为这个故事有两
我是一名优秀的程序员,十分优秀!