没有朋友授予访问私有构造函数的权限?

时间:2017-03-29 06:52:16

标签: c++ constructor private friend

我正在处理一些代码,我遇到了与此类似的情况:

struct Bar;

struct Foo{
    friend struct Bar;
private:
    Foo(){}
    void f(){}
    void g(){}
};

struct Bar {
   Foo* f;
   Bar()  { f = new Foo();}
   ~Bar() { delete f;}
};

int main(){
  Bar b;
}

我希望Bar不是friend的{​​{1}},因为除了Foo之外,构造函数Foo不需要访问任何Bar 1}}私有方法(因此不应该有访问权限)。有没有办法只允许Foo创建Bar而不让他们成为朋友?

PS :意识到问题可能不是100%明确。我不介意是否是通过朋友,只是所有Foo都可以访问所有私人方法的事实令我感到不安(这通常是Bar的情况),这就是我的意思我想避免。幸运的是,到目前为止,没有一个答案对这个糟糕的表述有问题。

3 个答案:

答案 0 :(得分:9)

这正是attorney-client成语的用语:

struct Bar;

struct Foo {
    friend struct FooAttorney;
private:
    Foo(){}
    void f(){}
    void g(){}
};

class FooAttorney {
  static Foo* makeFoo() { return new Foo; }
  friend struct Bar;
};

struct Bar {
   Foo* f;
   Bar()  { f = FooAttorney::makeFoo();}
   ~Bar() { delete f;}
};

int main(){
  Bar b;
}

在一个模仿生活方式的代码中,该类宣布了一名律师,该律师将调解其愿意与选定的一方分享的秘密。

答案 1 :(得分:5)

如果你不想引入另一个类,你可以缩小友谊圈,并使Bar的构造函数Foo成为朋友。它要求Bar的{​​{1}}定义可供Foo使用,它仍然允许Bar的构造函数无限制地访问Foo的私有实现:

struct Foo;

struct Bar {
   Foo* f;
   Bar();
   ~Bar();
};

struct Foo{
    friend Bar::Bar();
private:
    Foo(){}
    void f(){}
    void g(){}
};

Bar::Bar() : f(new Foo()) {
}

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

这并不能达到你想要的效果,但它使友谊更具针对性。

答案 2 :(得分:3)

我遇到的一种方法是让内部class使Bar成为其朋友,这样只有Bar可以创建它,内部class可以用作Foo构造函数的附加参数,因此只有class的朋友可以调用它。

class Foo
{
public:
    // only friends of the special key can invoke the constructor
    // or any member function that includes it as a dummy parameter
    class special_key {friend class Bar; special_key(){}};

    // making special_key a dummy parameter makes sure only friends of
    // the special key can invoke the function
    Foo(special_key) {}
    void f(){}
    void g(){}
};

class Bar
{
public:
    // only Bar functions can create the special key
    Bar() { f = std::make_unique<Foo>(Foo::special_key()); }

private:
    std::unique_ptr<Foo> f;
};

除了限制对特定功能的访问之外,这种技术还允许使用智能指针make功能,这种功能不会引导友谊。