目录
一、什么是分离编译
二、为什么不能
三、解决方案
1、模板定义的位置显式实例化
2、将声明和定义放到同一个文件里,不让定义和声明分离。
一、什么是分离编译
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有
目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。
二、为什么不能
假如有以下场景,模板定义与声明分离,在头文件中进行声明,源文件中完成定义
我们看看会如何
template.h
定义
template <class T>
class vector
{
public:
vector(int capacity = 12);
private:
T* pdate;
int _day;
int _capacity;
};
template.cpp
声明
template <class T>
vector<T>::vector(int capacity)
:pdate(new T[capacity])
, _day(1)
, _capacity(capacity)
{}
test.cpp
int main()
{
vector<int> v1;
vector<double> v2;
return 0;
}
会产生链接错误
为什么会这样?
我们要知道,从源文件到可执行文件,一般要进行以下步骤:
在汇编这一步中,编译器会生成符号表,符号表里面存着各各函数的地址,在链接的时候由main函数中调用的vector<int >,vectot<double>函数去符号表里寻找地址,这时出错了!
符号表里面这时没有存vector<int >,vectot<double>的地址,
因为template.cpp里存的是类模板,并没有实例化,因此符号表中并不会生成vector<int >,vectot<double>的地址,所以分离编译模板在连接时出错了,因为链接时会去调用vector<int >,vectot<double>,但是他俩没有地址,链接出错。
三、解决方案
1、模板定义的位置显式实例化
2、将声明和定义放到同一个文件里,不让定义和声明分离。