【发布时间】:2018-06-22 21:06:29
【问题描述】:
全部,
我正在使用 C++14,并且正在制作或多或少的标准 Singleton。我正在使用最新的 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;
但是,当我将单例实例的创建更改为:
instance = std::make_unique<A>();
我在尝试访问私有成员时遇到编译错误:
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
这对我来说就像一个错误,因为这两种形式在功能上应该是相同的?想法?
【问题讨论】:
-
类似于stackoverflow.com/q/33905030/241631。
make_unique和其他函数一样,为什么它可以调用你类的私有成员? -
无论如何,你可以通过将函数定义为
static A& getInstance() { static A instance; return instance; }来避免这一切 -
两种解决方案都存在竞争条件和重入问题。也就是说,单身人士通常被认为是一个坏主意,所以无论如何我都会避免这样做。
-
@UlrichEckhardt Praetorian 解决方案中的竞争条件是什么? Meyers Singleton 从 C++11 开始是线程安全的,并且 OP 已经表明他们正在使用 C++14。
-
@DGehlhaar 正如 Nevin 所说,我发布的内容在 C++11 之后已经是线程安全的。而且我仍然没有看到动态分配将解决的静态初始化顺序问题与函数本地静态相比(仅在您第一次调用
getInstance时进行初始化)
标签: c++ singleton c++14 unique-ptr private-constructor