|
多重继承使得沿多个路径继承名称成为可能。 沿这些路径的类成员名称不一定是唯一的。 这些名称冲突称为“多义性”。
任何引用类成员的表达式必须采用明确的引用。 以下示例说明如何产生多义性:
// deriv_NameAmbiguities.cpp
// compile with: /LD
// Declare two base classes, A and B.
class A {
public:
unsigned a;
unsigned b();
};
class B {
public:
unsigned a(); // class A also has a member "a"
int b(); // and a member "b".
char c;
};
// Define class C as derived from A and B.
class C : public A, public B {};
对于前面的类声明,如下所示的代码是不明确的,因为 b 所指的 b 是在 A 中还是在 B 中并不清楚:
C *pc = new C;
pc->b();
请看前面的示例。 由于名称 a 是类 A 和类 B 的成员,因此编译器无法辩明哪个 a 指定将调用函数。 如果成员可以引用多个函数、对象、类型或枚举数,则对该成员的访问是不明确的。
编译器通过按此顺序执行测试来检测多义性:
如果对名称的访问是不明确的(如上所述),则会生成错误消息。
如果重载函数是明确的,则将解析它们。
如果对名称的访问违背了成员访问权限,则会生成错误消息。 (有关详细信息,请参阅成员访问控制。)
在表达式通过继承产生多义性时,您可以通过限定考虑中的名称及其类名来手动消除该多义性。 若要适当编译上面的示例而不产生多义性,请使用如下代码:
C *pc = new C;
pc->B::a();
备注
在声明 C 时,如果在 B 的范围内引用 C,则可能会导致出现错误。 但不会发出任何错误,直到在 B 的范围内实际创建对 C 的非限定引用。
|
|