在没有朋友的情况下授予对私有构造函数的访问权限?

Grant access to private constructor without friends?

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

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 而不是 Foofriend,因为除了 Foo 的构造函数 Bar 不需要访问任何Foos 私有方法(因此不应该访问)。有没有办法只允许Bar创建Foo而不让他们成为朋友?

PS:意识到问题可能不是100%清楚。我不介意是否通过朋友,只是所有 Bar 都可以访问所有私有方法这一事实让我感到不安(通常 friends 就是这种情况),这就是我想避免。幸运的是,到目前为止给出的答案中有 none 这个糟糕的表述存在问题。

这正是 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;
}

在模仿生活时尚的代码中,class 声明了一位代理人,将调解它愿意与选定的各方分享的秘密。

如果不想介绍另一个class,可以缩小朋友圈,加Bar的构造器Foo为好友。它要求 Bar 的定义对 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;
}

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

我想到的一种方法是有一个内部 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 功能,而直接友谊不会。