2
class A {};

class B : private A {

};

class C : public B {
public:
    void f() {
        A a; // This line causes error, but works when it is in main() function
    }

};

int main()
{
    C c;
    // A a; --> This line works
    return 0;
}

我猜这与B私下继承有关,A但不能指望它。

编辑:错误是“A 类不可见”。用 g++ 编译。

4

2 回答 2

12

名称查找与访问检查是分开的。当您从一个类继承时,该类的名称被注入到继承类的范围中。所以在课堂C上你拿起名字A,但它是不可访问的。


一种解决方案是编写::A a;而不是A a;.

于 2013-01-31T00:58:47.120 回答
3

虽然 Alf 的回答是正确的,但我觉得它可以更清楚一点(或者可能更令人困惑,谁知道呢)。类的名称被注入到类本身的范围内。正如他所提到的,只有在查找找到标识符的含义后才会检查访问说明符。在有问题的代码中:

class A {};
class B : private A {};
struct C : public B {
    void f() {
        A a; // This line causes error, but works when it is in main() function
    }
};

在处理时C::f,编译器会看到标识符A并尝试解析它。它在范围内搜索C但它不存在,它向上移动层次结构并且在 中找不到它B,但它在基本类型中找到它A(查找将不合格解析A::A::A)。在这种情况下,标识符A被解析为我的基类 B 的基类 A 中的注入名称 A,并检查访问说明符。编译器检查它是否可以访问我的基类 B,然后它是否可以访问它的基类 A但是这个由于private继承而无法访问,并抱怨你无法访问A里面的嵌套名称A.

通过提供额外的限定::A,您可以指导查找。在这种情况下,它将A在全局命名空间中找到该类型,该类型是完全可访问的,并且会编译。

于 2013-01-31T02:30:46.563 回答