2013-12-20 79 views
0

我有一个情况我想隐藏一个基类和限制,可以从它继承的类:交通不便当朋友结构继承类

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::Base是无法进入ABC,即使他们是Private的朋友。我之前使用过这种模式没有问题,但与其他时间相比,我无法真正看到有什么不同。我没有看到什么?

+0

'abstract final'? –

+0

'friend struct A;'在名称空间'_detail'中声明一个结构为朋友。 – dyp

+0

@sftrabbit它的工作原理,为什么不呢? – NmdMystery

回答

3

C++语言不允许你使用合格的名字(例如::A)在朋友的声明,除非这些合格的名称是指先前声明的实体。实际上,这个规则在任何地方都是虚拟的,不仅在朋友声明中:合格的名字必须引用先前声明的实体。

在您的情况下,您在朋友声明friend struct ::A中使用了限定名称::A。为此,编译器必须事先知道来自全局名称空间的struct A。在你的情况下A没有宣布在这一点上,这使得friend struct ::A声明格式不正确。它甚至不应该按照语言的正式规则进行编译。

如果你的编译器接受这个,你必须咨询你的编译器documentatuion来找出它的含义。我怀疑friend struct ::A对于未知::A被解释为等同于friend struct A,即它声明_detail::A作为朋友。

如果您在声明名称空间_detail前进行了前向声明struct A;,它可能会使其按预期工作。