嵌套类(其表现得像朋友,但都没有)的访问(Access of nested classes (whi

2019-10-17 16:49发布

如果没有长时间的延迟,这里的代码,我不知道为什么它做什么,它的作用:

#include <iostream>

class A {
private:
  void print() { std::cout << "A.print() called" << std::endl; };
public:
  template<typename Foo>
  class B; //NOTE: no friend!
public:
  A();
  B<double>*  bd;
  B<int>*     bi;
}; 

template<typename Foo>
class A::B{
  A* callback;
public:
  B(A* a):callback(a){};
  void print() { callback->print(); }; // Why is this working ???
};

A::A():bd(new B<double>(this)),bi(new B<int>(this)){}

int main(int argc, char **argv)
{
  A a;
//   a.print(); // error: ‘void A::print()’ is private
  a.bd->print();
  a.bi->print();

  A::B<char> c(&a);
  c.print();

  A::B<double> d = *a.bd;
  d.print();

  return 0;
}

那么,它创建了一个输出中:

A.print() called
A.print() called
A.print() called
A.print() called

但为什么?

背景

我最初开始我的旅程下来的兔子洞时,我遇到了一个问题,我通过对有做哪些friend秒。 所以,我读友元声明没有宣布前方 (与所提到的答案, 在这里和这里 )。 因此,试图建立一个简单的例子(其中,您在上面看到的结果),我发现,我似乎实际上并不需要friend都没有。

因此,这里的底线问题: 为什么实例A::B有机会获得A民营函数A::print() (虽然我不知道,我可能误解了什么我的孩子 are-- 的孩子 ,而不是衍生的 基础与)

Answer 1:

因为嵌套类是封闭类的一个成员

标准$ 11.7.1

“嵌套类是一个部件,因此具有相同的访问权的任何其他成员的封闭类的成员具有为嵌套类的成员没有特殊的访问;通常的接入规则应服从”

和通常的访问规则规定:

“一类的成员也可以访问到的所有类访问的名字......”

具体的例子已经给出了标准:

class E {
    int x;
    class B { };

    class I {
        B b; // OK: E::I can access E::B
        int y;
        void f(E* p, int i) {
            p->x = i; // OK: E::I can access E::x
        }
    };
}


Answer 2:

嵌套类(或内部类)可以访问它嵌套内的类的阴部。 这在某种意义上已经是朋友了与类。 它类似于任何方式A对象可以访问任何其他的士兵A对象。

您可以使用friend的那些类之外定义您要访问它的私处类。 下面是一个简单的例子:

struct B;

class A
{
  int x;
  friend struct B;
};

struct B
{
  void someFunc() {
    A a;
    a.x = 5;
  }
};

int main(int argc, const char* argv[])
{
  B b;
  b.someFunc();
  return 0;
}

未做B的朋友A ,它不会是能够访问A的成员x



文章来源: Access of nested classes (which behave like friends, but aren't)