Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple inheritance ambiguous base class

Consider the code

struct Base{};
struct Derived: public Base{};

struct A: public Base{};

struct B: public A, public Base{};

struct C: public A, public Derived{}; // why no ambiguity here?

int main() {}

The compiler (g++5.1) warns that

warning: direct base 'Base' inaccessible in 'B' due to ambiguity struct B: public A, public Base{};

I understand this, Base is duplicated in B.

  1. Why is there no warning for C? Doesn't C inherit from both A and Derived, which both inherit from Base?

  2. Why adding virtual

    struct Derived: virtual Base{};
    

results now in both B and C emitting warnings, live on Wandbox

warning: direct base 'Base' inaccessible in 'B' due to ambiguity struct B: public A, public Base{};

warning: direct base 'Base' inaccessible in 'C' due to ambiguity struct C: public A, public Derived{};

like image 384
vsoftco Avatar asked May 15 '15 19:05

vsoftco


People also ask

How can we resolve ambiguity in multiple inheritance?

Ambiguity in inheritance can be defined as when one class is derived for two or more base classes then there are chances that the base classes have functions with the same name. So it will confuse derived class to choose from similar name functions. To solve this ambiguity scope resolution operator is used “::”.

Can you inherit from multiple base classes?

You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance. The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.

How many base classes are there in multiple inheritance?

Explanation: For the implementation of multiple inheritance, there must be at least 3 classes in a program. At least 2 base classes and one class to inherit those two classes. If lesser, it becomes single level inheritance.


1 Answers

In B, it's impossible to refer to members of the Base subobject inherited directly. Consider:

struct Base {
    int x;
};

struct B: public A, public Base {
    void foo() {
        int& x1 = A::x; // OK
        int& x2 = x; // ambiguous
        // no way to refer to the x in the direct base
    }
};

In C this is not a problem. Both x's can be referred to using qualified names:

struct C: public A, public Derived {
    void foo() {
        int& x1 = A::x; // OK
        int& x2 = Derived::x; // OK
    }
};

So the warning you get is one that only makes sense when a direct base is also inherited through another path.

For your second question, I couldn't reproduce the warning with C on Coliru with g++-5.1.

like image 132
Brian Bi Avatar answered Oct 27 '22 00:10

Brian Bi