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

发布于 2024-11-16 18:01:04 字数 1261 浏览 2 评论 0原文

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?
    };
  };
};

当我试图移植一个开源项目在borland下编译时,出现了这个友谊问题。根据 parashift 和两个半相关的问题< a href="https://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends">此处 和 此处,上面的示例应该无效。

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

因此,这提出了几个问题:

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

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

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?
    };
  };
};

This friendship issue came up when I was trying to port an open source project to compile under borland. According to parashift and two semi-related questions here and here, the above example should not be valid.

However, after testing it on seven different compilers1, only borland and dmc complained. This behavior surprised me because I wasn't expecting friendship to be transitive in nested classes.

So this raises a couple of questions:

  • What is the right behavior? I'm guessing it's the one accepted by most compilers.
  • If this is the correct behavior, why is this instance of friendship transitivity ok?
  • If this is correct then that would also imply a change in the standard. What might be the reasons for allowing this in the standard?
  • For compilers that rejected this code, what would be an appropriate workaround? Keep in mind that an actual project might contain fairly deep nesting so I'm looking for a solution that's semi-scalable.

1. tested on mingw-gcc 4.5.2, clang, borland c++ builder2007, digital mars, open watcom, visualc2010 and comeau online

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不爱素颜 2024-11-23 18:01:04

在 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)...

请参阅此缺陷报告

In C++03, nested class cannot access private and protected members of enclosing class by default (see §11.8/1). But if you make them friend of the enclosing classs, then they can access them. But again nested class of nested class is still not friend of the outermost enclosing class, the nested class of the nested class cannot access private and protected members of the outermost enclosing class; it cannot even access the private and protected member of the immediate enclosing class, as noted earlier. What you're doing is that, hence that is not allowed.

The C++ Standard (2003) says in $11.8/1 [class.access.nest],

The members of a nested class have no
special access to members of an
enclosing class
, nor to classes or
functions that have granted friendship
to an enclosing class; the usual
access rules (clause 11) shall be
obeyed. The members of an enclosing
class have no special access to
members of a nested class;
the usual
access rules (clause 11) shall be
obeyed.

Example from the Standard itself:

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
   }
};

Its a defect in the C++03 Standard.

By the way, its a defect in the C++03 Standard. Since the nested class is a member, it should have access to private and protected members, just like any other member:

§9.2/1 (C++03):

Members of a class are data members, member functions (9.3), nested types… Nested types are classes (9.1, 9.7) and enumerations (7.2) defined in the class…

See this Defect Report :

贪恋 2024-11-23 18:01:04

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

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

我能想到的最好的办法就是制作一个包装器:

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

I somehow feel that this should be allowed. Though I am not sure about the standard behavior. Someone can point out.

For compilers that rejected this code,
what would be an appropriate
workaround?

Best I can think of is to make a wrapper:

struct private_object::make_public
{
  static void wrap_method1() { private_object::method1(); }
  // use wrap_method1() everywhere else
  // ...
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文