【发布时间】:2010-10-02 04:27:24
【问题描述】:
当我使用模板为类编写 C++ 代码并在源 (CPP) 文件和头 (H) 文件之间拆分代码时,在链接最终可执行文件,尽管目标文件已正确构建并包含在链接中。这里发生了什么,我该如何解决?
【问题讨论】:
当我使用模板为类编写 C++ 代码并在源 (CPP) 文件和头 (H) 文件之间拆分代码时,在链接最终可执行文件,尽管目标文件已正确构建并包含在链接中。这里发生了什么,我该如何解决?
【问题讨论】:
模板类和函数在使用之前不会被实例化,通常在单独的 .cpp 文件中(例如程序源)。使用模板时,编译器需要该函数的完整代码才能构建具有适当类型的正确函数。但是,在这种情况下,该函数的代码在模板的源文件中有详细说明,因此不可用。
由于所有这些,编译器只是假设它是在其他地方定义的,并且只插入对模板化函数的调用。在编译模板的源文件时,程序源中使用的特定模板类型并没有在那里使用,因此它仍然不会生成函数所需的代码。这会导致无法解析的外部符号。
对此可用的解决方案是:
当编译器试图在程序源代码中构建类型化函数时,通过让编译器访问模板化函数的完整代码,1 和 2 基本上都解决了这个问题。
【讨论】:
.cpp文件有什么用?
另一种选择是将代码放在 cpp 文件中,并在同一个 cpp 文件中添加具有您希望使用的类型的模板的显式实例化。如果您知道您只会将它用于您预先知道的几种类型,这将非常有用。
【讨论】:
basic_string<T> 之类的东西,你只会将它与char 或wchar_t 一起使用,所以如果将所有实现放在标题中是担心,在 cpp 中实例化它是一种选择。代码是你的命令,反之亦然。
对于包含 .h 文件的每个文件,您应该插入两行:
#include "MyfileWithTemplatesDeclaration.h"
#include "MyfileWithTemplatesDefinition.cpp"
样本
#include "list.h"
#include "list.cpp" //<---for to fix bug link err 2019
int main(int argc, _TCHAR* argv[])
{
list<int> my_list;
my_list.add_end(3);
.
.
}
另外,你不要忘记将你的声明类放在 centinel 常量中
#ifndef LIST_H
#define LIST_H
#include <iostream>
.
.
template <class T>
class list
{
private:
int m_size,
m_count_nodes;
T m_line;
node<T> *m_head;
public:
list(void);
~list(void);
void add_end(T);
void print();
};
#endif
【讨论】: