make_unique 不会编译用于创建单例实例

DGe*_*aar 2 c++ singleton private-constructor unique-ptr c++14

全部,

我正在使用 C++14,并且正在制作一个或多或少的标准单例。我正在使用最新的 Visual Studio 2017。此代码有效:

#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;
Run Code Online (Sandbox Code Playgroud)

但是,当我将单例实例的创建更改为:

instance = std::make_unique<A>();
Run Code Online (Sandbox Code Playgroud)

我在尝试访问私有成员时收到编译错误:

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    
Run Code Online (Sandbox Code Playgroud)

这对我来说感觉像是一个错误,因为这两种形式在功能上应该是相同的?想法?

Adr*_*n W 6

的目的std::unique_ptr<>是控制所指向对象的生命周期。您可以传递 a std::unique_ptr<>around,但这也会转移所指向对象的所有权。这个概念与单例的概念不太相符。只有一个地方允许创建(或删除)单例。你真的不需要一个std::unique_ptr<>。正如评论中已经说过的,有更简单的方法。我更喜欢@Praetorian的建议:

static A& getInstance() 
{
     static A instance;
     return instance;
}
Run Code Online (Sandbox Code Playgroud)

不能使用std::make_unique<>()构造函数来实例化类的原因是构造函数是私有的。要访问它,您需要访问函数是friend. 看看如何让 std::make_unique 成为我班上的朋友。另一种解决方案是提供一个需要私有类型作为参数的公共构造函数,如此解决方案中所述。