朋友应该在嵌套类中传递吗?

gre*_*olf 5 c++ standards-compliance friend

class private_object
{
private:
  struct make_public;
  friend struct make_public;
  static void method1() {}
};

struct private_object::make_public
{
  class nested_outer
  {
    void callFromOuter() 
    { private_object::method1(); }   // Should this be an error?

    class nested_inner
    {
      void callFromInner() 
      { private_object::method1(); } // How about this one?
    };
  };
};
Run Code Online (Sandbox Code Playgroud)

当我试图将一个开源项目移植到borland下编译时,这个友谊问题出现了.根据这里这里的parashift和两个半相关的问题,上面的例子不应该是有效的.

然而,在七个不同的编译器1上测试之后,只有borland和dmc抱怨.这种行为让我感到惊讶,因为我并不期望友谊在嵌套类中是可传递的.

所以这提出了几个问题:

  • 什么是正确的行为?我猜它是大多数编译器都接受的.
  • 如果这是正确的行为,为什么这个友谊传递的实例可以呢?
  • 如果这是正确的,那么这也意味着标准的变化.在标准中允许这样做的原因是什么?
  • 对于拒绝此代码的编译器,什么是适当的解决方法?请记住,实际项目可能包含相当深的嵌套,因此我正在寻找一种半可扩展的解决方案.

1.测试mingw-gcc 4.5.2,clang,borland c ++ builder2007,数字火星,开放式watcom,visualc2010和comeau在线

Naw*_*waz 3

在 C++03 中,默认情况下,嵌套类无法访问封闭类的private成员(请参阅 \xc2\xa711.8/1)。protected但是如果你让他们成为封闭类的朋友,那么他们就可以访问它们。但是嵌套类的嵌套类仍然不是最外层封闭类的友元,嵌套类的嵌套类不能访问最外层封闭类的私有和受保护成员;如前所述,它甚至无法访问直接封闭类的私有成员和受保护成员。你正在做的就是那样,因此这是不允许的。

\n\n

C++ 标准 (2003) 在 $11.8/1 [class.access.nest] 中说,

\n\n
\n

嵌套类的成员对封闭类的成员没有特殊访问权限,也对已向封闭类授予友谊的类或函数没有特殊访问权限;应遵守通常的访问规则(第 11 条)。封闭类的成员对嵌套类的成员没有特殊访问权限;\n 应遵守通常的访问规则(第 11 条)。

\n
\n\n

标准本身的示例:

\n\n
class E \n{\n    int x;\n    class B { };\n    class I \n    {\n        B b; // error: E::B is private\n        int y;\n        void f(E* p, int i)\n        {\n           p->x = i; // error: E::x is private\n        }\n   };\n   int g(I* p)\n   {\n       return p->y; // error: I::y is private\n   }\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

这是 C++03 标准中的一个缺陷。

\n\n

顺便说一句,这是C++03 标准中的一个缺陷。由于嵌套类是一个成员,它应该有权访问私有和受保护的成员,就像任何其他成员一样:

\n\n

\xc2\xa79.2/1 (C++03):

\n\n
\n

类的成员有数据成员、成员函数(9.3)、嵌套类型\xe2\x80\xa6 嵌套类型是类\xe2\x80\xa6 中定义的类(9.1、9.7)和枚举(7.2)

\n
\n\n

请参阅此缺陷报告

\n\n\n