朋友访问受保护的嵌套类

时间:2010-08-27 13:03:24

标签: c++ friend

我有以下C ++代码:

class A {
 protected:
  struct Nested {
    int x;
  };
};

class B: public A {
  friend class C;
};

class C {
  void m1() {
    B::Nested n; // or A::Nested
  }
};

使用g ++ 4.4编译这个片段,无论我在m1中使用B :: Nested还是A :: Nested,都没有区别。 Clang接受B::Nested,但如果我A::Nested则不会编译。这是g ++或clang中的错误吗?

2 个答案:

答案 0 :(得分:8)

根据标准,GCC是正确的,而且Clang是错的。它说是11.2 / 4

  

如果

,则在N类中命名时可以访问成员m      
      
  • m作为N的成员受到保护,并且引用发生在N类的成员或朋友中,或者发生在从N派生的P类的成员或朋友中,其中作为P的成员的m是私有的或受保护的
  •   

这是这个Clang bugreport的主题,它阻止了Clang构建Qt:http://llvm.org/bugs/show_bug.cgi?id=6840。一个Clang家伙说

  

实际上,我还没有实施过这条规则。它要么是一个   起草错误或可怕的错误。它整个'受保护'   说明符,它使得代码的良好形成依赖于   存在完全不相关的类,它会带来很高的成本   实现,并且在模板存在的情况下它是正式不可判定的。

答案 1 :(得分:1)

在C ++中,朋友不是传递性的。朋友的朋友不一定是我的朋友。

通过在A中使Nested受保护,您指示所有子类都可以使用此元素,但是不允许其他人使用它。你可以认为这是一种朋友。 A使所有子类成为关于访问嵌套结构的朋友。

现在B使C成为朋友,但这并不意味着C也是A的朋友。所以C应该无法访问嵌套。

但是:行为是从C ++ 03改变的。在C ++ 03中,嵌套类是封闭类的完整成员,因此具有完全访问权限。友谊仍然不是传递性的,但现在成员访问是。

您可能需要查看http://www.rhinocerus.net/forum/language-c-moderated/578874-friend-transitive-nested-classes.html,这解释了类似的问题。