2009-12-05 100 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>; 
相关问题