I'm struggling with a (let me say) corner case of the std::make_shared
function and I didn't manage to find a viable alternative to my (not-so-serious) problem.
The following code compiles fine:
#include <memory>
class A {
A() = default;
A(const A &) = default;
A(A &&) = default;
A& operator=(const A &) = default;
A& operator=(A &&) = default;
public:
static std::shared_ptr<A> create() {
// std::shared_ptr<A> ptr = std::make_shared<A>();
std::shared_ptr<A> ptr{new A};
return ptr;
}
};
int main() {
auto ptr = A::create();
}
It's intuitively a small example of a kind of factory for an user defined class named A.
By looking at the documentation of std::make_shared
, we find that:
This function is typically used to replace the construction std::shared_ptr(new T(args...)) of a shared pointer from the raw pointer returned by a call to new. In contrast to that expression, std::make_shared typically allocates memory for the T object and for the std::shared_ptr's control block with a single memory allocation (this is a non-binding requirement in the Standard), where std::shared_ptr(new T(args...)) performs at least two memory allocations.
Quite interesting, it would help maybe switching the commented line with the one immediately after. It results in the following code for the function create
:
static std::shared_ptr<A> create() {
std::shared_ptr<A> ptr = std::make_shared<A>();
// std::shared_ptr<A> ptr{new A};
return ptr;
}
Unfortunately, this version does not compile because of the private constructor(s) of A
(the error is something like error: ‘constexpr A::A()’ is private
).
To be clear, the problem is not the error for itself, it's quite clear to me what's due to and it makes sense. Anyway, I'd like to know if there is a workaround to be able to use the std::make_shared
function and let the constructors to be private at the same time. As far as I can see, the code in the first example seems to be the only available solution, even if it goes without saying that it has a well known (and documented) drawback in terms or performance.