Grant access to private constructor without friends?

拜拜、爱过 提交于 2019-12-03 12:52:05
StoryTeller - Unslander Monica

This is precisely what the attorney-client idiom is for:

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

In a code imitates life fashion, the class declares an attorney that will mediate the secrets it's willing to share with the selected parties.

If you do not want to introduce another class, you can shrink the circle of friendship and make Bar's constructor Foo's friend. It requires Bar's definition to be available to Foo, and it still gives Bar's constructor unrestricted access to Foo's private implementation:

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

This does not achieve exactly what you want, but it makes friendship a lot more targeted.

One way that occurred to me was to have an internal class that makes Bar its friend so only Bar can create it and that internal class can be used as an additional parameter to Foo constructor so only the class's friends can invoke it.

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

As well as restricting access to specific functions this technique also allows the use of smart pointer make functions which direct friendship does not.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!