我无意中遇到了多重继承中使用的类中具有相同名称的成员变量的问题。我的基本想法是成员变量是简单的“合并”,即发生多重声明。编译器甚至没有告诉我警告,请参阅下面的 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
,它查找子对象包含以此方式命名的成员以及该成员。它还从最派生的对象类型开始,并“向上”查找基类子对象,直到找到某些内容(简而言之,这也是 C++ 中成员名称隐藏的工作方式)。
So for e->I
,它寻找I
in E
。该搜索没有找到任何内容,因此它进入了基类主题。它发现SW2::I
,引用定义在中的唯一成员的名称SW2
。所以它停止了。
If没有SW2::I
,它将继续寻找并找到两者Other::I
and HW::I
。现在在两个不同的基类子对象中发现了相同的名称,我们得到了歧义。不是含糊不清的警告,而是直截了当地表达e->I
模棱两可,这是一个错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)