C++多重继承私有成员冲突访问

4
以下代码:
class A1 {
public:
    int x;
};
class A2 {
private:
    int x() { return 67; }
};

class M : public A1, public A2 {};

int main() {
    M m;
    m.x;
}

编译错误:

error C2385: ambiguous access of 'x'
note: could be the 'x' in base 'A1'
note: or could be the 'x' in base 'A2'

但为什么?只有 A1::x 应该对 M 可见,A2::x 应该是纯粹的本地的。

2
在C++中,在执行成员访问检查之前会发生名称查找 - WhiZTiM
你的问题之前已经被问过了: http://stackoverflow.com/questions/6397938/ambiguous-access - Dave S
1个回答

5
在C++中,名称查找发生在成员访问检查之前。因此,在名称查找(在您的情况下是未限定的)中找到了两个名称,这是不明确的。
您可以使用限定名称来消除歧义:
int main() {
    M m;
    m.A1::x;     //qualifed name-lookup
}

1
@tower120,不是关于ADL的。当进行非成员函数的未限定查找时,Koenig Lookup会发挥作用。 - WhiZTiM
顺便问一下,这是历史遗留问题还是有意为之(为了某个目的)?对我来说,起初看起来像编译器的 bug,但现在看起来更像是语言本身的问题 :) - tower120
1
不,这不是语言错误。这是你期望访问控制影响名称查找的问题。如果访问控制影响了名称查找(例如改变了可接受的匹配项),那么通过简单地将“private”更改为“public”或反之亦然,就可以故意或更糟糕地意外地显着改变工作代码的行为方式。最好提醒程序员存在歧义(就像发生在你身上的那样),而不是在面对微小变化时代码变得脆弱。 - Peter
3
这是一个错误的论点。改变访问级别并不是一个“小改变”,当真的存在一个错误时,你会得到一个预期中的错误。同样的问题也会影响简单的类继承。它会破坏类的封装逻辑,因为你在基类中定义了一个私有成员,派生类就不能再自由地使用那个名称了。 - jj99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接