友元结构继承类时无法访问

时间:2013-12-20 22:11:24

标签: c++ inheritance visual-c++ friend access-control

我有一种情况,我想隐藏基类并限制可以从中继承的类:

namespace _detail {
    class Private abstract final {
        struct Base abstract {
        protected:
            Base() {}
        };

        friend struct ::A;
        friend struct ::B;
        friend struct ::C;
    };
}

struct A : _detail::Private::Base {}; //error
struct B : _detail::Private::Base {}; //error
struct C : _detail::Private::Base {}; //error

编译器告诉我,_detail::Private::BaseAB无法访问C,即使他们是Private的朋友。我之前使用过这种模式没有问题,而且与其他时候使用它相比,我无法真正看到这里有什么不同。我没看到什么?

1 个答案:

答案 0 :(得分:3)

C ++语言不允许您在好友声明中使用限定名称(如::A),除非这些限定名称引用以前声明的实体。实际上,这条规则适用于所有地方,不仅适用于朋友声明:限定名称必须引用先前声明的实体。

在您的情况下,您在朋友声明::A中使用了限定名friend struct ::A。为了实现这一点,必须事先为编译器知道全局命名空间中的struct A。在您的情况下,A未在此时声明,这使得friend struct ::A声明格式不正确。它甚至不应该通过正式的语言规则进行编译。

如果你的编译器接受了这个,你必须查阅你的编译器文档来弄清楚它的含义。我怀疑未知friend struct ::A的{​​{1}}被解释为等同于::A,即它将friend struct A声明为朋友。

如果在声明命名空间_detail::A之前发出前向声明struct A;,它可能会使其按预期工作。