首先需要认知以下几点 :
- 编译器只编译cpp文件,不单独编译.h文件
- 编译器在编译阶段是独立编译的
- 编译一个cpp文件时,展开包含的头文件,发现一个调用在当前文件无法找到,就标记为一个符号
- 类模板产生的符号跟该模板的任何具体类的符号都不同
代码:
假设三个文件分别是Temp.h Temp.cpp main.cpp(我们举最简单的栗子以方便理解)
//Temp.h
template<typename Type>
class CTemp
{
CTemp();
};//Temp.cpp
#include "Temp.h"
template<typename Type>
CTemp<Type>::CTemp()
{
}//main.cpp
#include <iostream>
using namespace std;
#pragma warning(disable:4996)
#include "Temp.h"
int main()
{
CTemp<int> a;
return 0;
}编译后报错如下:
分析:
在编译Temp.cpp时,模板的构造被导出符号我们假设为a1,在编译main.cpp时,我们根据模板定义一个具体类的对象,但是即使展开了头文件,我们还是找不到构造的定义,就在这里标记一个导入符号a2(表示我们需要在链接阶段导入一个符号a2才能运行).
编译阶段结束了,我们要进行最后的阶段链接了,凡是需要导入符号的,都要找到这个符号,将真正的调用导入才行.结果找了半天,发现没有跟a2相匹配的符号,就报错说,无法解析这个外部的符号
解决方案:
- 在.cpp文件中使用类模板显式实例化
template CTemp<int>; - 在main函数中包含”Temp.cpp”文件,一般改名为”Temp.hpp”,来表示是一个头文件形式的cpp文件(很绕)
- .h文件和.cpp文件写在一起
- 在.cpp文件中随便写个函数中使用了CTemp模板类就会提供一个导出符号a1
// 在Temp.cpp中任意位置加上这句
void Func()
{
CTemp<int> temp;
}版权声明:本文为saodilaoshu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。