C++ 当使用多重继承时,为什么这个限定名不明确?
我试图使用底部对象访问struct Top中的成员变量x 代码如下:C++ 当使用多重继承时,为什么这个限定名不明确?,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,我试图使用底部对象访问struct Top中的成员变量x 代码如下: #include <cstdio> struct Top { public: int x = 1; }; struct Left : public Top { int x = 2; }; struct Right : public Top { int x = 3; }; struct Bottom : public Left, public Right { int x = 4
#include <cstdio>
struct Top
{
public:
int x = 1;
};
struct Left : public Top
{
int x = 2;
};
struct Right : public Top
{
int x = 3;
};
struct Bottom : public Left, public Right
{
int x = 4;
};
int main()
{
Bottom b;
std::printf("value: %d\n", b.Left::Top::x);
return 0;
}
这个歧义是如何用一个限定的名字来访问的?
< p>问题是C++没有直接表达“多层次”类成员的概念,例如“<代码>代码> >代码> >代码>左< /代码>的子成员>代码> x<代码>。Left::Top::x
的意思是“由Left::Top
表示的类型中的成员x
”——而由Left::Top
表示的类型正好是Top
这就是为什么你可以写一些奇怪的东西,比如
int Left::* ptr = &Right::Top::x;
因为=
的右侧完全等同于&Top::x
,并且指向基类成员的指针可以隐式转换为指向派生类成员的指针。(此转换的结果仍然引用派生类的基类子对象中的成员。)
为了消除歧义,您可以按照
static_cast(b).Top::x
或使用指向成员的指针-givenint Left::*ptr=&Top::x
,b.*ptr
将引用b
的Left
子对象的Top
子对象中的x
,Left
和Right
都继承自Top
,并且都有一个数据成员x
。这是不明确的,因为Left
和Right
是Top
的子类,每个子类都定义了x
。如果Bottom
同时对这两个类进行子类化,则无法从Left
或Right
确定x
。请注意,您的限定名并不含糊,您的继承结构是含糊不清的。我知道访问多重继承菱形的非限定成员是含糊不清的。这里的问题是,如果我完全限定它,为什么它仍然模棱两可。例如,如果我先向左然后向上静态强制转换,我可以访问正确的x值。为什么它对限定名不起作用?有趣的是,您可以通过编写int Left::*ptr=&Left::Top::x;通过指向成员的指针进行访问然后访问b.*ptr
,但我怀疑这是最好的解决方案。您还可以编写((左&)b).Top::x
来获取它。然而,我没有一个建设性的答案来解释为什么最初的用法是模棱两可的。你能在另一个编译器上复制这个吗?我相信查找Left::Top::x
的方法是“在类Left
中找到类型Top
,然后在该类型的范围内找到名称x
”,因此它完全等同于Top::x
(在第一步中找到的名称Top
是注入的类名)。
int Left::* ptr = &Right::Top::x;