Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
145 views
in Technique[技术] by (71.8m points)

c++ - Multiple inheritance + virtual function mess

I have a diamond multiple inheritance scenario like this:

    A
  /   
 B     C
     /
    D

The common parent, A, defines a virtual function fn().
Is it possible for both B and C to define fn()?
If it is, then the next question is - can D access both B and C's fn() without disambiguation? I'm assuming there is some syntax for this..
And is it possible for D to do that without knowing specifically who are B and C? B and C can be replaces by some other classes and I want the code in D to be generic.

What I'm trying to do is to have D somehow enumerate all of the instances of fn() it has in its ancestry. Is this possible in some other means that virtual functions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...