我不小心遇到了在多重继承中使用的类中具有相同名称的成员变量的问题。我的基本想法是成员变量是简单的“合并”,即发生了多个声明。编译器甚至没有告诉我警告,请参阅下面的MWE。
我知道让变量具有相同的名称是一个坏主意,因此我认为以我的方式引用它们至少是模棱两可的。所以我期望至少会有警告或错误。
1)为什么编译器没有至少写出警告?
2)如何在内部解决这些变量的处理? (我想使用了别名,例如HW::I和Other::I,但是它们与SW1::I和SW2::I的关系如何?)
#include <iostream>
struct Other { int I;};
struct HW { int I;};
struct SW1 : Other, HW { int I;};
struct SW2 : HW, Other { int I;};
struct D : SW1 { };
struct E : SW2 { };
int main()
{
E* e = new E;
D* d = new D;
e->I = 3;
SW1* pc1 = dynamic_cast<SW1*>(d);
pc1->I = 2;
std::cerr << d->I;
std::cerr << e->I;
SW2* pc2 = dynamic_cast<SW2*>(e);
pc2->I = 1;
std::cerr << d->I;
std::cerr << e->I;
}
最佳答案
编译器正确无误,无法诊断您的代码有任何问题。正如您所构造的那样,该代码并不模糊。本质上,如果一个名称与多个变量(或您的情况下的类成员)具有同等的匹配性,则该名称是模棱两可的。
在评估e->I
时,找到的第一个候选对象是I
,它是SW2
类的成员(通过继承)。 I
从其基类继承的SW2
成员与Sw2
直接定义的成员不匹配。
同样,pc1->I
无疑是SW1
的成员,d->I
相同,并且pc2->I
无疑是基类SW2
的成员。
如果e->I
没有自己的名为SW2
的成员(即I
(.),则在评估struct SW2: HW, Other {};
时会出现歧义。 name然后考虑了两个基类e->I
和SW2
,它们都有一个名为I
的成员,它们都是很好的匹配,因此HW
表达式是模棱两可的-编译器将发出诊断信息,即错误(不仅仅是警告)。在这种情况下,程序员可以使用范围(Other
)运算符来显式解决歧义,例如,可以完全限定名称的I
或e->I
。
没错,在类层次结构中多次使用名称是个坏主意。既因为很难以对编译器有意义的方式正确解决歧义,又因为仅仅凡人通常很难遵循逻辑。