多继承模糊基类

时间:2015-05-15 19:31:20

标签: c++ inheritance multiple-inheritance

考虑代码

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() {}

编译器(g ++ 5.1)警告

  

警告:由于含糊不清'Base''B'无法访问基座struct B: public A, public Base{};

我理解这一点,BaseB中重复。

  1. 为什么C没有警告? CA都继承Derived并且都继承自Base

  2. 为什么要添加virtual

    struct Derived: virtual Base{};
    
  3. > Wandbox

      

    警告:由于含糊不清BC无法访问基座'Base'

         

    警告:由于含糊不清'B'struct B: public A, public Base{};无法访问基座'Base'

2 个答案:

答案 0 :(得分:2)

B中,无法直接引用Base子对象的成员。考虑:

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

C这不是问题。 x>都可以使用限定名称来引用:

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

所以你得到的警告只有当 direct 基地也通过另一条路径继承时才有意义。

对于你的第二个问题,我无法在Coliru上使用C使用g ++ - 5.1重现警告。

答案 1 :(得分:2)

没有办法明确地访问“B”中的Base成员,而在“C”中则可以,如下面的代码所示:

#include <iostream>

using namespace std;

struct Base
{
    void print()
    {
        cout << "Base" << endl;
    }
};

struct Derived : public Base {};

struct A : public Base
{
    void print()
    {
        cout << "A" << endl;
    }
};

struct B : public A, public Base
{
    void print()
    {
        A::print();

        //error (ambiguous), no way to access to Base::print => warning
        //Base::print();
    }
};

struct C : public A, public Derived
{
    void print()
    {
        A::print();
        Derived::print(); // Not Ambiguous, it's the Base inherited by 'Derived' which is used.
        // Still an error but you can access print indirectly through "Derived" => no warning needed
        //Base::print();
    }
};

int main() 
{
    B b;
    b.print();

    C c;
    c.print();

    return 0; 
}