嵌套类构造函数调用私有构造函数,它有效吗?

时间:2014-04-25 12:44:26

标签: c++ constructor friend

此代码似乎有效,但我不确定原因:

#include <iostream>

class Foo {
  friend class Bar;
public:
  void printNum() {std::cout << num_ << "\n";}
private:
  // This constructor is private, should be accessible only to Bar
  Foo(int num) : num_(num) {}
  int num_;
};

class Bar {
public:
  Bar(int num);
  void printFooNum();
  ~Bar();
private:
  class Impl_;
  Impl_ * pImpl_;
};

struct Bar::Impl_ {
  Impl_(int num);
  Foo foo_;
};

Bar::Impl_::Impl_(int num)
  : foo_(num)
{}

Bar::Bar(int num)
  : pImpl_(new Impl_(num))
{}

void Bar::printFooNum() {
  pImpl_->foo_.printNum();
}

Bar::~Bar() { delete pImpl_;}

int main() {
  Bar bar(5);

  bar.printFooNum();

  return 0;
}

在这里,我试图确保类Foo的对象可以在类Bar的对象内构造,这是使用pImpl模式实现的。我实际上并不介意构造函数Bar::Impl_()显然能够调用Foo构造函数,但我不确定为什么它应该工作。这段代码是使用几个不同的编译器(GCC和Intel)编译的,它似乎给了我想要的结果,但我不确定是不是因为编译器是允许的,或者代码实际上是正确的。

为什么当Bar::Impl_()仅与Foo而不是Foo结识时,Bar可以调用Bar::Impl_构造函数?

4 个答案:

答案 0 :(得分:1)

显然,朋友类的所有成员都可以访问宣布他们为朋友的班级的所有成员。由于嵌套结构被视为成员,因此嵌套的Bar可以访问所有Foo的成员。见这里:http://www.drdobbs.com/friendly-nesting/184401866

答案 1 :(得分:1)

朋友类的嵌套成员可以访问授予友谊的类的私有成员和受保护成员的名称。

C ++标准版n3337 11.3 § 2:

  

声明一个类成为朋友意味着私有和   可以访问授予友谊的类的受保护成员   在base-specifiers 和成为友好的成员声明中   类即可。 [例如:

class A {           // *your Foo

    class B { };    // *private 

    friend class X; // *your Bar
     

};

struct X : A::B { // OK: A::B accessible to friend

    A::B mx;      // OK: A::B accessible to member of friend

    class Y {       // *your Impl

        A::B my;  // OK: A::B accessible to nested member of friend

    }; 
};

答案 2 :(得分:0)

嵌套类具有与方法相同的访问权限:它们可以访问包含类的private个部分,

class Outer {
    struct Nested {
        static void touch_private(Outer &x) {
            x.private_member = 1;
        }
    };

    int private_member;

  public:
    Nested() {
        Inner::touch_private(*this);
    }
};

......和外面的朋友一样,就像它的私人部分一样。 (在这里插入笑话。)

答案 3 :(得分:0)

嗯,这是一个有趣的问题。但是,原因很明显:嵌套类是其封闭类的成员。作为成员,他们拥有封闭类的所有其他成员及其所有朋友的访问权限。 C ++ 03标准如此规定(§9.2/ 1(C ++ 03))