Multiple inheritance + virtual function mess

后端 未结 6 799
灰色年华
灰色年华 2020-12-02 23:50

I have a diamond multiple inheritance scenario like this:

    A
  /   \\
 B     C
  \\   /
    D

The common parent, A, defines a virtual fu

6条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-03 00:28

    Unless you overwrite fn again in D, no it is not possible. Because there is no final overrider in a D object: Both C and B override A::fn. You have several options:

    • Drop either C::fn or B::fn. Then, the one that still overrides A::fn has the final overrider.
    • Place a final overrider in D. Then, that one overrides A::fn aswell as fn in C and B.

    For example the following results in a compile time error:

    #include 
    
    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;
    }
    

    You can, however derive non-virtual from A in C and B, but then you have no diamond inheritance anymore. That is, each data-member in A appears twice in B and C because you have two A base-class sub-objects in an D object. I would recommend you to rethink that design. Try to eliminate double-objects like that that require virtual inheritance. It often cause such kind of conflicting situations.

    A case very similar to this is when you want to override a specific function. Imagine you have a virtual function with the same name in B and C (now without a common base A). And in D you want to override each function but give different behavior to each. Depending whether you call the function with a B pointer or C pointer, you have the different behavior. Multiple Inheritance Part III by Herb Sutter describes a good way of doing that. It might help you decide on your design.

提交回复
热议问题