多重继承歧义基class
Multiple inheritance ambiguous base class
考虑代码
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) 警告说
warning: direct base 'Base'
inaccessible in 'B'
due to ambiguity struct B: public A, public Base{};
我明白了,Base
在 B
中重复了。
为什么C
没有警告? C
不是同时继承自 A
和 Derived
,它们都继承自 Base
吗?
为什么要加virtual
struct Derived: virtual Base{};
结果现在 B
和 C
发出警告,继续 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{};
在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
}
};
因此,您收到的警告只有在 直接 基数也通过另一条路径继承时才有意义。
关于你的第二个问题,我无法在 Coliru 上用 g++-5.1 重现 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;
}
考虑代码
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) 警告说
warning: direct base
'Base'
inaccessible in'B'
due to ambiguitystruct B: public A, public Base{};
我明白了,Base
在 B
中重复了。
为什么
C
没有警告?C
不是同时继承自A
和Derived
,它们都继承自Base
吗?为什么要加
virtual
struct Derived: virtual Base{};
结果现在 B
和 C
发出警告,继续 Wandbox
warning: direct base
'Base'
inaccessible in'B'
due to ambiguitystruct B: public A, public Base{};
warning: direct base
'Base'
inaccessible in'C'
due to ambiguitystruct C: public A, public Derived{};
在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
}
};
因此,您收到的警告只有在 直接 基数也通过另一条路径继承时才有意义。
关于你的第二个问题,我无法在 Coliru 上用 g++-5.1 重现 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;
}