为什么单一虚拟继承不足以解决可怕的钻石问题?

发布于 2024-11-19 04:37:15 字数 480 浏览 4 评论 0原文

struct B { int i; };
struct D1 : virtual B {};
struct D2 : B {};  // <-- not virtual
struct DD : D1, D2 {};

完成上述编码后,编译器仍然要求 D2 也为 virtual

DD d;
d.i = 0; // error: request for member `i' is ambiguous

我不明白的是,一旦您提示编译器 B相对于DD(通过D1)来说是virtual那么为什么它仍然i不明确?

(如果我没记错的话,较旧的 VC++(2006 年)就足以通过单个虚拟继承来解决这个问题)

struct B { int i; };
struct D1 : virtual B {};
struct D2 : B {};  // <-- not virtual
struct DD : D1, D2 {};

Having coded above, still the compiler demands D2 also to be virtual:

DD d;
d.i = 0; // error: request for member `i' is ambiguous

What I don't understand is, once you have prompted compiler that B is virtual with respect to DD (via D1) then why it still i is ambiguous ?

(If my memory serves correct, the older VC++ (in 2006), was capable enough to make out this just with single virtual inheritance)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒绊 2024-11-26 04:37:15

B 相对于 DD 不是虚的 - 它相对于 D1 是虚的。创建 D2 时,它包含 B 的完整副本。因此,现在 DD 有 B 的两种实现:一种作为 D2 的一部分,另一种在末尾(由 D1 指向)。并且拥有两份i,使用它确实是有歧义的。

如果 D2 也使用虚拟继承,则它不会包含 B 的副本,而是包含一个指向 D1 也指向的 B 实例的指针,并且 DD 将仅包含 B 的一个实例。

我将尝试说明内存布局,希望结果正确...:

您的情况,有一个虚拟继承和一个非虚拟 -

|    D1    |   D2 + B |    B    |
+--+-------+----------+---------+
 |   vptr to B           ^
 +-----------------------|

让 D1 和 D2 都虚拟继承 -

|   D1   |   D2   |   B   |
+--+-----+---+----+-------+
 |         |         ^
 +---------+---------|

B is not virtual with respect to DD - it is virtual with respect to D1. At the time D2 is created, it contains a full copy of B. So now DD has two implementations of B: one as part of D2, and one at the end (pointed by D1). And having two copies of i, using it is indeed ambiguous.

Had D2 also used virtual inheritance, instead of containing a copy of B, it would have contained a pointer to the instance of B that D1 is also pointing at, and DD would have contained only one instance of B.

I'll try to illustrate the memory layouts, hope this comes out right...:

Your case, with one virtual inheritance and one non-virtual -

|    D1    |   D2 + B |    B    |
+--+-------+----------+---------+
 |   vptr to B           ^
 +-----------------------|

Having both D1 and D2 inherit virtually -

|   D1   |   D2   |   B   |
+--+-----+---+----+-------+
 |         |         ^
 +---------+---------|
栖竹 2024-11-26 04:37:15

您必须阅读钻石问题。在“方法”标题下,对于 CPP,明确提到了您的情况,您的观察结果与那里解释的情况相符。

You must read Diamond problem . Under the Approaches heading, for CPP, your case is clearly mentioned, your observation matches the one explained there.

乖不如嘢 2024-11-26 04:37:15

标准要求在这种情况下 di 必须是不明确的。 ISO/IEC 14882:2003 第 10.1.6 节涵盖了具有给定类型的虚拟和非虚拟基类的类。

The standard requires that d.i must be ambiguous in this case. ISO/IEC 14882:2003 section 10.1.6 covers classes with virtual and non-virtual base classes of a given type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文