代码之家  ›  专栏  ›  技术社区  ›  Torsten Marek

对受保护嵌套类的友元访问

  •  11
  • Torsten Marek  · 技术社区  · 15 年前

    我有以下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编译这个代码段,无论我是使用B::Nested还是使用M1中的A::Nested,都没有什么区别。Clang接受 B::Nested ,但如果我 A::Nested . 这是g++中的错误还是clang中的错误?

    2 回复  |  直到 15 年前
        1
  •  8
  •   Johannes Schaub - litb    15 年前

    根据标准,GCC是正确的,Clang是错误的。上面写着11.2/4

    在n类中命名时,成员m是可访问的,如果

    • m作为n的成员受到保护,并且引用出现在n类的成员或朋友中,或者出现在从n派生的p类的成员或朋友中,其中m作为p的成员是私有的或受保护的。

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

    实际上,我故意还没有执行这个规则。要么是 起草错误或可怕的错误。它使整个“受保护的”中性化。 说明符,它使代码的良好形式依赖于 存在完全无关的类,它对 实现,并且在模板存在的情况下,它在形式上是不可决定的。

        2
  •  1
  •   Matthieu M.    15 年前

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

    通过在中设置嵌套保护,可以指示所有子类都可以使用此元素,但其他任何子类都不允许使用它。你可以认为这是一种朋友。a使所有子类成为访问嵌套结构的朋友。

    现在b使c成为朋友,但这并不意味着c也是a的朋友,所以c不应该访问嵌套的。

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

    你可能想看看 http://www.rhinocerus.net/forum/language-c-moderated/578874-friend-transitive-nested-classes.html 这也解释了类似的问题。