C++ 当使用多重继承时,为什么这个限定名不明确?

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

我试图使用底部对象访问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;
}; 

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
或使用指向成员的指针-given
int 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;