在“经典”钻石问题中,如下所示(virtual
前面没有public D
的一个,在class C
和class B
后面),可以解决使用名称范围运算符::
产生歧义,例如在类A
的构造函数中:
/*
* D D D
* / \ which without 'virtual' | |
* B C is actually: B C
* \ / \ /
* A A
*/
#include <iostream>
using namespace std;
class D { public: char d = 'D';};
class C : public D { public: char c = 'C';};
class B : public D { public: char b = 'B';};
class A : public B, public C { public: char a = 'A'; A();};
A::A() {
cout << B::d; //This works! B's d, inherited from D.
cout << C::d; //This works! C's d, inherited from D.
//cout << D::d; //This doesn't work (ambiguous)
//cout << B::D::d; //Doesn't work either though.
//cout << C::D::d; //Doesn't work either though.
}
int main() {
A a;
cout << endl;
return 0;
}
现在考虑像这样的双钻石:
/*
* G G G G G
* / \ | | | |
* E F E F E F
* \ / \ / \ /
* D D D
* / \ which without 'virtual' | |
* B C is actually: B C
* \ / \ /
* A A
*/
#include <iostream>
using namespace std;
class G { public: char g = 'G';};
class E : public G { public: char e = 'E';};
class F : public G { public: char f = 'F';};
class D : public E, public F { public: char d = 'D';};
class C : public D { public: char c = 'C';};
class B : public D { public: char b = 'B';};
class A : public B, public C { public: char a = 'A'; A();};
A::A() {
cout << /* How do I reach any of the two e's or f's
or any of the four g's?*/
}
int main() {
A a;
cout << endl;
return 0;
}
[如何准确地到达从E,F和G继承的字段?对我而言,实际上最合乎逻辑的是以下内容。
cout << B::D::d;
cout << B::D::E::e;
cout << B::D::F::e;
cout << B::D::E::G::g;
cout << B::D::F::G::g;
cout << C::D::d;
cout << C::D::E::e;
cout << C::D::F::e;
cout << C::D::E::G::g;
cout << C::D::F::G::g;
但是(使用g ++)它们都产生'X' is an ambiguous base of 'A'.
形式的错误。
有人可以解释为什么这行不通,什么是正确的方法?我想念什么?
让我们从您遇到的错误开始。 'X' is an ambiguous base of 'A'.
不起作用的原因: