3

Consider the following code where I'd like to delegate the creation of an A object to a method called make, in order to allow users of the class to only create instances wrapped in a std::shared_ptr:

#include <memory>

class A {
private:    
    A() {}

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

int main() {
    std::shared_ptr<A> a = A::make();
    return 0;
}

I would have thought that, because make is a member function, it would be allowed to access the private constructor, but apparently that's not the case. Compiling the program fails with the following message in the source of std::shared_ptr:

/usr/include/c++/8/ext/new_allocator.h:136:4: error: ‘A::A()’ is private within this context

How can I solve this issue?

sigalor
  • 901
  • 11
  • 24
  • 1
    You could consider using the [pass key idiom](https://gist.github.com/RklAlx/6727537). – Eljay Jun 24 '19 at 11:57
  • 2
    This has nothing to do with the function being static. It's that `std::make_shared` is trying to construct an `A`, which it can't because the constructor is private. – Nikos C. Jun 24 '19 at 11:57

1 Answers1

0
class A {
private:
    A() {}

public:
    static std::shared_ptr<A> make() {
        return std::shared_ptr<A>(new A());
    }
};
Andy Nugent
  • 859
  • 7
  • 21
  • 2
    You lose the [benefits of make_shared](https://stackoverflow.com/a/20895705/856199) if you do that. – Nikos C. Jun 24 '19 at 12:00
  • The downside being two memory allocations, one for the shared_ptr control block, and one for the class A instance object. In contrast to `std::make_shared` which only will do one allocation for both the control block and object. May or may not be important, depending on the project and usage pattern. – Eljay Jun 24 '19 at 12:01
  • 1
    This is a clone of [this almost eight year old answer](https://stackoverflow.com/a/8147101/2311167) – Adrian W Jun 24 '19 at 13:31