2016-03-02 6 views
0

Я знаю, что существуют только реальные гарантии того, когда статическая переменная инициализируется. Самое главное (для меня), которое не гарантируется, - это порядок инициализации переменных в разных единицах компиляции, что вызвало следующий вопрос.getInstance - Class vs Method static

Я всегда писал свои одноэлементные классы, как это:

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; 
} 

Однако, насколько я понимаю, это не гарантирует, что экземпляр уже инициализирован (и, следовательно, вызов оператор 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; 
} 

на мой взгляд, это не только чище, но и лучший код, потому что теперь у меня есть гарантированный порядок инициализации.

Являются ли мои предположения правильными?

+0

Поскольку вы знаете, что '_instance' гарантированно будет инициализирован при первом вызове' getInstance', почему вам все еще нужно заявление 'if'? – Nard

+1

Потому что _instance не имеет значения. По умолчанию инициализация std :: shared_ptr хранит в ней нулевой указатель. – Thalhammer

+0

Если да, почему бы не инициализировать 'shared_ptr' с' новым A' сразу? – Nard

ответ

0

На самом деле _instance гарантированно будет инициализирован перед первым вызовом getInstance() (при условии, что они определены в одной и той же единице трансляции)

от стандартного 3.6.2-4 инициализации нелокальных переменных:

это определяется реализация ли выполняется динамическая инициализация нелокального переменного со статической продолжительностью хранения до первого утверждения основных. Если инициализация отложена до некоторого момента времени после первого утверждения main, она должна произойти до первого использования odr (3.2) любой функции или переменной , определенной в той же самой единице перевода, что и инициализированная переменная.35