C++ getInstance-类与静态方法

C++ getInstance-类与静态方法,c++,static,initialization,singleton,C++,Static,Initialization,Singleton,我知道静态变量初始化的时间只有真正的基本保证。(对我来说)最重要的事情是不能保证不同编译单元中变量的初始化顺序,这引发了以下问题 我总是这样编写我的单例类: class A { ... public: static std::shared_ptr<A> getInstance(); private: static std::shared_ptr<A> _instance; } == A.cpp == std::share

我知道静态变量初始化的时间只有真正的基本保证。(对我来说)最重要的事情是不能保证不同编译单元中变量的初始化顺序,这引发了以下问题

我总是这样编写我的单例类:

class A {
    ...
    public:
       static std::shared_ptr<A> getInstance();
    private:
       static std::shared_ptr<A> _instance;
}
== A.cpp ==
std::shared_ptr<A> A::getInstance() {
    if(!_instance)
       _instance = std::make_shared<A>();
    return _instance;
}
A类{
...
公众:
静态std::shared_ptr getInstance();
私人:
静态std::共享的\u ptr\u实例;
}
==A.cpp==
std::shared_ptr A::getInstance(){
if(!\u实例)
_instance=std::make_shared();
返回_实例;
}
然而,据我所知,如果我在任何其他静态对象的构造函数中调用此函数(在某些罕见的情况下,这可能发生在main开始执行之前),这并不保证实例已经初始化(因此调用运算符bool是有效的)

我的新想法如下:

 class A {
    ...
    public:
       static std::shared_ptr<A> getInstance();
}
== A.cpp ==
A& A::getInstance() {
    static std::shared_ptr<A> _instance = std::make_shared<A>();
    return _instance;
}
A类{
...
公众:
静态std::shared_ptr getInstance();
}
==A.cpp==
A&A::getInstance(){
静态std::shared_ptr_instance=std::make_shared();
返回_实例;
}
在我看来,这不仅仅是更干净,而且是更好的代码,因为现在我有了一个有保证的初始化顺序


我的假设正确吗?

实际上
\u实例
保证在第一次调用
getInstance()
之前初始化(前提是它们在同一翻译单元中定义)

根据标准3.6.2-4非局部变量的初始化

它是实现定义是否动态初始化一个具有静态存储的非局部变量 持续时间在main的第一个语句之前完成。如果初始化延迟到某个时间点 在main的第一个语句之后,它应出现在任何函数或变量的第一次odr使用(3.2)之前 在与要初始化的变量相同的转换单元中定义。35


既然您知道
\u instance
保证在第一次调用
getInstance
时被初始化,那么为什么还需要
if
语句呢?因为\u instance没有值。默认初始化std::shared_ptr会在其中存储一个空指针。如果是这样,为什么不立即用
新a
初始化
共享_ptr
呢?是的,用新a初始化它就行了。我没有想到这一点。但还有一种更好的方法:使用std::make_shared初始化,这既缩短了代码,又提供了make_shared的所有优点。我改变了我的榜样,你说得对!我肯定不知道
make_shared
比简单地用
new
构建更有效。谢谢