2014-11-02 123 views
1

我去的文件在從http://www.boost.org/doc/libs/1_47_0/boost/pool/detail/singleton.hpp爲什麼C++單例實例化需要do_nothing方法?

我的問題:既然create_object是類的靜態成員singleton_default它的構造應前主被調用。從object_creator的構造函數中,調用singleton_default :: instance,它確保obj在main之前實例化。我不遵循的是do_nothing方法的需要。文檔中提到它強制實例化create_object,但不是應該在main啓動之前初始化的類的靜態成員?通過該標記應該singleton_default :: create_object實例化不夠好?

下面的代碼

// T must be: no-throw default constructible and no-throw destructible 
template <typename T> 
struct singleton_default 
{ 
    private: 
    struct object_creator 
    { 
     // This constructor does nothing more than ensure that instance() 
     // is called before main() begins, thus creating the static 
     // T object before multithreading race issues can come up. 
     object_creator() { singleton_default<T>::instance(); } 
     inline void do_nothing() const { } 
    }; 
    static object_creator create_object; 

    singleton_default(); 

    public: 
    typedef T object_type; 

    // If, at any point (in user code), singleton_default<T>::instance() 
    // is called, then the following function is instantiated. 
    static object_type & instance() 
    { 
     // This is the object that we return a reference to. 
     // It is guaranteed to be created before main() begins because of 
     // the next line. 
     static object_type obj; 

     // The following line does nothing else than force the instantiation 
     // of singleton_default<T>::create_object, whose constructor is 
     // called before main() begins. 
     create_object.do_nothing(); 

     return obj; 
    } 
}; 
template <typename T> 
typename singleton_default<T>::object_creator 
singleton_default<T>::create_object; 

我試圖消除do_nothing方法,但在此之前主要是停止對象實例化。

回答

1

你必須看看的標準3.6.2初始化非局部變量

首先在第2點的原則:

變量與靜態存儲時間(...)應爲零初始化 任何其他初始化發生之前。執行

常數初始化:(...)

總之,零初始化和常數初始化被稱爲 靜態初始化;所有其他初始化都是動態的 初始化。在動態初始化發生之前,應執行靜態初始化。具有靜態存儲持續時間的非局部變量的動態初始化可以是有序的,也可以是無序的 。明確專用類模板的定義static 數據成員已經命令初始化。

然後在4點,你的問題的解釋(你單身,需要一個「動態intialisation」):

這是實現定義是否 非本地變量與動態初始化靜態存儲持續時間在 main的第一條語句之前完成。如果在main的第一個語句之後初始化被推遲到某個 時間點,它應該在 之前出現在同一個 翻譯單元中定義的任何函數或變量的第一個odr-use作爲要初始化的變量。

這個do_nothing()只是確保首次使用和動態初始化的順序。

你會不會有do_nothing(),全局靜態create_object()就不再需要你的instance()第一個電話,靜態obj這個函數內部之前initalized只會在第一次調用初始化,啓動之後即的main()

相關問題