Saturday, 18 October 2014

make_shared (and make_unique) for classes with private constructors

A common idiom is to have a privately constructable class with a (static) factory that returns a shared (or unique) pointer.

class A {
    A() {};

public:
    static std::shared_ptr<A> make() {
        return std::make_shared<A>();
    }
};
Looks simple and yet doesn't work since std::make_shared cannot access A's constructor.

I found a simple trick how to solve this without opening the class up to public construction: add a parameter with a private »cookie« to the constructor which proves that the class is being constructed »from within«.

class A {
    struct ctor_cookie {};

public:
    explicit A(ctor_cookie) {};
    static std::shared_ptr<A> make() {
        return std::make_shared<A>(ctor_cookie());
    }
};

1 comment:

  1. Nice idea! However, it creates a public ctor that just looks a bit weird in the API... With this technique, there is probably no way around this, I guess.

    ReplyDelete