多重继承歧义基类

Multiple inheritance ambiguous base class

本文关键字:基类 歧义 多重继承      更新时间:2023-10-16

考虑以下代码

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)警告

警告:由于歧义struct B: public A, public Base{};

我明白了,BaseB中是重复的。

  1. 为什么没有C的警告?C不是同时继承ADerived吗? CC_8和CC_9都继承'Base'0 ?

  2. 为什么添加virtual

    struct Derived: virtual Base{};
    

结果现在BC都发出警告,live on Wandbox

警告:由于struct B: public A, public Base{};歧义,'B'无法访问直接基'Base'

警告:由于struct C: public A, public Derived{};歧义,'C'无法访问直接基'Base'

'B'0中,不能引用直接继承的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
    }
};
所以你得到的警告只有在直接基也通过另一个路径继承时才有意义。

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

无法明确地访问"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; 
}