All,
I am using C++14 and am making a more-or-less standard Singleton. I am using the latest Visual Studio 2017. This code works:
#include <memory>
class A
{
public:
static A& getInstance()
{
if (instance == nullptr)
instance = std::unique_ptr<A>(new A());
return *instance;
}
private:
A() {}
static std::unique_ptr<A> instance;
};
std::unique_ptr<A> A::instance = nullptr;
However, when I change the creation of the singleton instance to this:
instance = std::make_unique<A>();
I get a compilation error that I am trying to access a private member:
Error C2248 'A::A': cannot access private member declared in class 'A'
c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\memory 2510
This feels like a bug to me, as the two forms should be identical in function? Thoughts?
The purpose of std::unique_ptr<>
is to control the lifetime of the object pointed to. You may pass a std::unique_ptr<>
around, but that will also transfer ownership of the object pointed to. This concept does not match very well with the concept of a singleton. There is only one place that is ever allowed to create (or delete) the singleton. You don't really need a std::unique_ptr<>
for that. As already said in the comments, there are simpler ways for that. I would prefer @Praetorian's suggestion:
static A& getInstance()
{
static A instance;
return instance;
}
The reason why you can't use std::make_unique<>()
to instantiate your class is that the constructor is private. To access it, you need the accessing function to be a friend
. Have a look at How to make std::make_unique a friend of my class for that. Another solution is to provide a public constructor requiring a private type as argument, as described int this solution.