【问题标题】:Are friends supposed to be transitive in nested classes?朋友应该在嵌套类中传递吗?
【发布时间】:2011-09-19 04:12:16
【问题描述】:
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?
    };
  };
};

当我尝试移植一个开源项目以在 b​​orland 下编译时,出现了这个友谊问题。根据parashift和两个半相关的问题herehere,上面的例子应该是无效的。

然而,在 7 个不同的编译器1 上对其进行测试后,只有 borland 和 dmc 抱怨。这种行为让我感到惊讶,因为我没想到友谊在嵌套类中是可传递的。

所以这提出了几个问题:

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

1。在 mingw-gcc 4.5.2、clang、borland c++ builder2007、digital mars、open watcom、visualc2010 和 comeau online 上测试

【问题讨论】:

    标签: c++ friend standards-compliance


    【解决方案1】:

    我觉得这应该是允许的。虽然我不确定标准行为。有人可以指出来。

    对于拒绝此代码的编译器, 什么是合适的 解决方法?

    我能想到的最好的方法是做一个包装器:

    struct private_object::make_public
    {
      static void wrap_method1() { private_object::method1(); }
      // use wrap_method1() everywhere else
      // ...
    };
    

    【讨论】:

      【解决方案2】:

      在 C++03 中,嵌套类不能默认访问封闭类的 privateprotected 成员(参见 §11.8/1)。但是如果你让它们成为封闭类的朋友,那么它们就可以访问它们。但是嵌套类的嵌套类仍然不是最外层封闭类的朋友,嵌套类的嵌套类不能访问最外层封闭类的私有成员和受保护成员;如前所述,它甚至不能访问直接封闭类的私有和受保护成员。你正在做的是那样,因此这是不允许的。

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

      嵌套类的成员没有 对成员的特殊访问 封闭类,也不是类或 赋予友谊的功能 到封闭类;通常 访问规则(第 11 条)应 服从了。 封闭的成员 类没有特殊的访问权限 嵌套类的成员; 通常 访问规则(第 11 条)应 服从。

      标准本身的示例:

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

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

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

      §9.2/1 (C++03):

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

      查看此缺陷报告

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多