【问题标题】:Why is single virtual inheritance not enough to resolve the dreaded diamond problem?为什么单一虚拟继承不足以解决可怕的钻石问题?
【发布时间】:2011-07-08 06:03:58
【问题描述】:
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 相对于DDvirtual(通过D1)那么为什么它仍然i 是模棱两可的?

(如果我没记错的话,较早的 VC++(2006 年)仅通过单个 virtual 继承就足以证明这一点)

【问题讨论】:

    标签: c++ language-lawyer virtual-inheritance diamond-problem


    【解决方案1】:

    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   |
    +--+-----+---+----+-------+
     |         |         ^
     +---------+---------|
    

    【讨论】:

      【解决方案2】:

      您必须阅读Diamond problem。在“方法”标题下,对于 CPP,您的案例被明确提及,您的观察结果与那里解释的一致。

      【讨论】:

      • 这是一个很好的链接,但正如你所说;它显示了观察结果。我想知道它背后的原因。引擎盖下发生了什么(简而言之)。
      • 我认为关于 Virtual Inheritance 的文章可能更有助于更深入地了解幕后发生的事情。
      • 维基百科链接不是答案。
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2012-04-19
        • 2017-12-09
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 2011-02-09
        • 1970-01-01
        相关资源
        最近更新 更多