我有一个像这样的菱形多重继承方案:

    A
  /   \
 B     C
  \   /
    D

公用父项A定义了虚函数fn()。
B和C都可以定义fn()吗?
如果是,那么下一个问题是-D是否可以毫无歧义地访问B和C的fn()?我假设有一些语法。
D可能会在不特别了解B和C是谁的情况下这样做吗? B和C可以被其他一些类替代,我希望D中的代码通用。

我想做的是让D以某种方式枚举其祖先拥有的fn()的所有实例。这是否有可能以其他方式实现虚拟功能?

最佳答案

除非您再次用fn覆盖D,否则不可能。因为D对象中没有最终的替代程序,所以CB都替代A::fn。您有几种选择:

  • 删除C::fnB::fn。然后,仍然覆盖A::fn的那个将具有最终的覆盖器。
  • 在D中放置一个最终的替代程序。然后,该替代程序将A::fn以及fnC中的B覆盖。

  • 例如,以下结果导致编译时错误:
    #include <iostream>
    
    class A {
    public:
        virtual void fn() { }
    };
    
    class B : public virtual A {
    public:
        virtual void fn() { }
    };
    
    class C : public virtual A {
    public:
        virtual void fn() { }
    };
    
    // does not override fn!!
    class D : public B, public C {
    public:
        virtual void doit() {
            B::fn();
            C::fn();
        }
    };
    
    int main(int argc, char **argv) {
      D d;
      d.doit();
      return 0;
    }
    

    但是,您可以从C和B中的A派生非虚拟对象,但是这样您就不再具有菱形继承(钻石问题)。也就是说,A中的每个数据成员在B和C中出现两次,因为在D对象中有两个A基类子对象。我建议您重新考虑该设计。尝试消除需要虚拟继承的双对象。它通常会导致这种冲突情况。

    当您要覆盖特定功能时,情况与此非常相似。想象一下,您有一个在B和C中具有相同名称的虚函数(现在没有通用的基数A)。在D中,您想覆盖每个函数,但是给每个函数不同的行为。根据使用B指针还是C指针调用函数,您会得到不同的行为。 Herb Sutter的Multiple Inheritance Part III描述了一种很好的方法。它可以帮助您决定设计。

    关于c++ - 多重继承+虚拟函数困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/616380/

    10-11 22:42
    查看更多