考虑代码
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{};
我理解这一点,Base
在B
中重复。
为什么C
没有警告? C
和A
都继承Derived
并且都继承自Base
?
为什么要添加virtual
struct Derived: virtual Base{};
> Wandbox
警告:由于含糊不清B
,C
无法访问基座'Base'
警告:由于含糊不清'B'
,struct B: public A, public Base{};
无法访问基座'Base'
答案 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;
}