2012-07-12 32 views
2

Possible Duplicate:
Why can templates only be implemented in the header file?辛格爾頓C++模板類

我意識到,已經有這樣幾個主題對SO,但我沒有發現任何會回答我的問題。

我一直在使用本教程http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin

但不幸的是我不斷收到錯誤已經寫我的模板單例類:

/home/USER/testcode/cpp_workshop/main.cpp:-1: error: undefined reference to `Singleton::Instance()' :-1: error: collect2: ld

我singleton.h

#ifndef SINGLETON_H 
#define SINGLETON_H 

template <typename T> 
class Singleton 
{ 
public: 
    static T& Instance(); 

protected: 
    virtual ~Singleton(); 
    inline explicit Singleton(); 

private: 
    static T* _instance; 
    static T* CreateInstance(); 
}; 

template<typename T> 
T* Singleton<T>::_instance = 0; 

#endif // SINGLETON_H 

singleton.cpp

#include "singleton.h" 
#include <cstdlib> 

template <typename T> 
Singleton<T>::Singleton() 
{ 
    assert(Singleton::_instance == 0); 
    Singleton::_instance = static_cast<T*>(this); 
} 

template<typename T> 
T& Singleton<T>::Instance() 
{ 
    if (Singleton::_instance == 0) 
    { 
     Singleton::_instance = CreateInstance(); 
    } 
    return *(Singleton::_instance); 
} 

template<typename T> 
inline T* Singleton<T>::CreateInstance() 
{ 
    return new T(); 
} 

template<typename T> 
Singleton<T>::~Singleton() 
{ 
    if(Singleton::_instance != 0) 
    { 
     delete Singleton::_instance; 
    } 
    Singleton::_instance = 0; 
} 

,這就是我怎麼稱呼它(與normall - 不是模板或任何東西 - 類GameSingleton<Game>::Instance().run();

+0

你有沒有包含頭文件中main.cpp中? – 2012-07-12 13:23:30

+0

@EamonnMcEvoy是的,我確實包括了它們兩個('game.h'和'singleton.h') – Patryk 2012-07-12 13:25:50

+0

模板函數定義在使用這些函數的地方必須對編譯器可見。因此你不能把它們放在單獨的'.cpp'文件中。 – n0rd 2012-07-12 13:28:54

回答

3

把你方法定義在頭類定義下,並刪除您的CPP。模板化類的模板化方法和方法必須在頭文件中定義(帶有一些駭人的例外)。

每請求時,這裏是「hackish的例外」:

  • 1)查看@Desmond休謨的回答
  • 2)僅使用模板類從這些定義的方法的CPP。例如,你可以在cpp中的一個未命名的命名空間中聲明/定義一個模板化的類,這很好。
+0

它確實編譯了:)希望它在運行時不會導致任何問題... – Patryk 2012-07-12 13:30:44

+0

@Dave那些「黑客例外」會是什麼? – 2012-07-12 13:48:19

+0

@DesmondHume編輯包括他們。 – David 2012-07-12 13:52:14

0

它不可能分開模板類的定義(頭文件)和實現(cpp)。 所以你有兩種解決方案之一:

1-實現頭文件中的所有內容.h。像這樣的東西

template <typename T> 
class Singleton 
{ 
public: 
    static T& Instance(){} 

protected: 
    virtual ~Singleton(){} 
    inline explicit Singleton(){} 

private: 
    static T* _instance; 
    static T* CreateInstance(){} 
}; 

另一種解決方案是將.cpp類重命名爲.hpp。不要將.h文件包含在.hpp文件中,而是反過來。即包括.h文件中

我個人比較喜歡第一個解決方案

乾杯

+1

「它不被編譯器接受」 - 這是不正確的。我知道有兩種情況允許cpps中的模板類的方法。 1)顯式實例化你要使用的類的類(參見Desmond Hume的答案)2)如果模板的唯一位置在cpp中,則定義爲 – David 2012-07-12 13:33:12

+0

任何人都可以在提供的.cpp文件中實現模板化方法該方法所屬的類在該文件或其他.cpp文件中顯式實例化。在靜態/動態庫的情況下更好。 – 2012-07-12 13:45:08

+0

對不起,我不清楚,通過實現我的意思是分離模板類的頭和實現 – 2012-07-12 14:48:34

2

你可以把你的Singleton類的定義爲頭文件你可以保持分離內.HPP文件聲明(頭文件)和定義(.cpp文件),因爲它是現在如果你喜歡它更好,並且明確實例化Singleton類與您將使用它的每個類型。要顯式實例Singleton類,可以嘗試以下的.cpp文件的末尾:

template 
class Singleton<Game>; 

與其他類型看起來會以同樣的方式:

template 
class Singleton<AnotherGame>; // just for example