【问题标题】:Nested class constructor calls private constructor, and it works?嵌套类构造函数调用私有构造函数,它有效吗?
【发布时间】:2014-06-11 04:39:29
【问题描述】:

这段代码似乎可以工作,但我不知道为什么:

#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)编译的,它似乎给了我想要的结果,但我不确定这是因为编译器允许还是代码实际上是正确的。

为什么Foo 只与Bar 成为朋友而不是Bar::Impl_ 时,Bar::Impl_() 似乎可以调用Foo 构造函数?

【问题讨论】:

    标签: c++ constructor friend


    【解决方案1】:

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

    【讨论】:

    • 我想我以前看过 Dobbs 博士的那篇文章,我从中得到的结论是,您所说的仅在 C++ 标准的更高版本中是正确的,而不是严格的 C++98 .但是,嘿,如果编译器对后期标准的支持足够广泛,我会接受它。
    【解决方案2】:

    嵌套类与方法具有相同的访问权限:它们可以访问包含类的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】:

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

      【讨论】:

        【解决方案4】:

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

        C++ 标准 n3337 11.3 § 2:

        将一个类声明为友元意味着 private 和 可以访问授予友谊的类的受保护成员 在 base-specifiers 和 befriended 的成员声明中 类。 [ 例子:

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

        【讨论】:

          猜你喜欢
          • 2012-09-14
          • 2021-09-19
          • 2011-04-20
          • 2019-10-16
          • 2011-02-08
          相关资源
          最近更新 更多