2009-12-05 93 views
8

工作,我有一個基於模板類[Allotter.h & Allotter.cpp]:鏈接錯誤 '解析外部符號':使用模板

template <typename allotType> class Allotter { 
public: 
Allotter(); 
quint32 getAllotment(allotType*); 
bool removeAllotment(quint32, int auto_destruct = 0); 

private: 
QVector<QPair<quint32, allotType*>> indexReg; 
int init_topIndex; 
}; 

,它的使用量顯示爲[ActiveListener.h & ActiveListener。 cpp]:

class ActiveListener: public QObject { 
Q_OBJECT 

public: 
ActiveListener(); 

private slots: 
    void processConnections(); 
    void readFromSocket(int); 

private: 
QTcpServer* rootServer; 
QSignalMapper* signalGate; 
Allotter<QTcpSocket> TcpAllotter; 
}; 

我沒有顯示完整的定義,因爲它並不重要。問題是當我編譯時,所有文件都能正確編譯。這些文件在一個VC++項目中。早些時候,當我沒有使用基於模板的方法Allotter時,一切都在編譯和鏈接正常。但現在,我得到這個錯誤:

1>ActiveListener.obj : error LNK2019: unresolved external symbol "public: __thiscall Allotter<class QTcpSocket>::Allotter<class QTcpSocket>(void)" ([email protected]@@@@[email protected]) referenced in function "public: __thiscall ActiveListener::ActiveListener(void)" ([email protected]@[email protected]) 
1>ActiveListener.obj : error LNK2019: unresolved external symbol "public: unsigned int __thiscall Allotter<class QTcpSocket>::getAllotment(class QTcpSocket *)" ([email protected][email protected]@@@@[email protected]@@Z) referenced in function "private: void __thiscall ActiveListener::processConnections(void)" ([email protected]@@AAEXXZ) 

令人吃驚的是,該構造,ActiveListener::ActiveListener()不會使所有Allotter<QTcpSocket>::Allotter()任何引用。然而第二個參考確實存在。但我不明白爲什麼鏈接器無法解析這個外部符號。

中出現錯誤之前生成的輸出是:

1>Moc'ing ActiveListener.h... 
1>Compiling... 
1>stdafx.cpp 
1>Compiling... 
1>ActiveListener.cpp 
1>Allotter.cpp 
1>moc_ActiveListener.cpp 
1>main.cpp 
1>Generating Code... 
1>Linking... 

我不明白,如果任何這是相關的,主要是因爲這一切完全使用之前的工作。這只是在我使用模板之後引起了一個問題。 任何幫助將不勝感激。非常感謝。

+0

謝謝大家對您所提供的幫助量。我做了一些自己的研究,並找到了相同問題的解決方案:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13 我把它放在這裏對於偶然碰巧在這裏尋找解決類似問題的其他人。 再次感謝:D – 2009-12-06 04:46:34

+0

[「未定義符號」鏈接器錯誤與簡單模板類的可能重複](http://stackoverflow.com/questions/999358/undefined-symbols-linker-error-with-simple-template-class ) – 2010-06-28 20:02:42

回答

16

您不能將模板拆分爲.h和.cpp文件 - 您需要將模板的完整代碼放入.h文件。

+5

除非你使用'export',它只適用於童話故事。 – 2009-12-05 17:48:33

+0

@Charles:'export'在現實生活中(與Comeau編譯器一起工作)。 – 2009-12-05 17:53:34

+0

非常感謝:D 你能否告訴我爲什麼會發生這種情況?我假設只要編譯器需要一個來自MyClass 的MyClass 的特定類,它就需要有源代碼來生成所需的類。 對嗎? – 2009-12-05 17:54:36

1

由於您不能將模板實現放置在.cpp文件中,因此對模板實現使用.inl文件並將其包含在模板標頭中是一種很好的做法。

4

一般來說,最好的做法是將模板代碼完全寫入頭文件。這是一個重要的技術原因:當你實例化一個模板時,C++編譯器需要從該模板生成特定於你指定的模板參數的代碼。如果您的模板代碼完全放在您的標題中,則會自動爲您完成。

絕對有可能以您擁有的方式編寫模板代碼,並將實現放置在cpp文件中。但是,如果您這樣做,則需要顯式實例化您打算使用的模板實例。

在你的情況,你需要添加下面一行到.cpp文件在您的項目:

template class Allotter<QTcpSocket>; 
相關問題