2012-08-31 62 views
8

定義考慮下面的結構:C++模板和靜態成員 - 在頭

//! Templated singleton. 
/*! 
    Template wrapper enforcing the singleton behavior. 
*/ 
template <class T> 
class TSingleton 
{ 
private:  
    //! Singleton instance pointer. 
    static T* instance; 
    //! private constructor. 
    TSingleton() { } 
    //! private empty copy constructor. 
    TSingleton(const TSingleton<T>& sourceObject) {} 

public: 
    //! Static singleton instance getter. 
    static T* GetInstance() 
    { 
     if (instance == 0) 
      instance = new T(); 
     return instance; 
    } 

}; 

template <class T> T* TSingleton<T>::instance = 0; 

這個模板類和靜態實例的定義都寫在同一個頭文件。對於非模板類,由於爲實例靜態成員定義了多個符號,因此此會導致鏈接時錯誤。對於模板來說,這似乎也很直觀,因此必須將定義分開並放在.cpp文件中。但模板通常是在類頭文件中聲明和定義的。 這是什麼讓這種語法對模板類有效和功能?

這裏有一個wikipedia鏈接,但它沒有提供關於模板類的情況的明確解釋。

回答

13

這工作,因爲要複製[basic.def.odr]/5明確允許模板:

可以有不止一個類類型的一個定義(第9條),枚舉類型(7.2),外部鏈接內聯函數(7.1 .2),類模板(第14章),非靜態函數模板(14.5.6),類模板的靜態數據成員(14.5.1.3),類模板的成員函數(14.5.1.1)或模板特化在程序中沒有指定一些模板參數(14.7,14.5.5),前提是每個定義出現在不同的翻譯單元中,並且提供的定義滿足以下要求。 ...

要求是相當冗長的,所以我不會在這裏複製它們,但基本上他們聲明每個重複的定義必須相同(否則程序有未定義的行爲)。