模板
模板是编写与类型无关的逻辑代码(泛型编程),是复用的一种方式。
模板类形式:
template<class/typename 形参名>;
class 类名
{……};
模板函数形式:
template<class/typename 形参名>;
函数类型 函数名(参数列表)
{……}
分离编译
一个项目由多个源文件组成,每个源文件会单独编译成各自的目标文件,通过链接将各个源文件的目标文件链接成一个可执行文件的过程。
但是在编译模板程序的时候往往这样会出现错误:
这种错误是链接时错误,一般是因为声明的函数在链接时没有找到函数的实现体。
因为模板是实例化之后才会生成有效地代码,实例化之前只会检查函数的形式是否错误,不会检查模板函数体内的代码是否正确。
具体分析:
下面是给出的程序的 .h 和 .cpp 文件:
//template.h
template <class T>
class Data
{
public:
Data();//声明函数
public:
T year;
T month;
};
//template.cpp
#include "template.h"
template <class T>//定义函数
Data<T>::Data()
:yera(0)
, month(0)
{
}
//main.cpp
#include "template.h"
int main()
{
Data<int> d;//调用函数
}
在编译main.cpp文件的过程中,main.cpp知道template.h文件中对函数Data()的声明,调用Data()函数就形成一条call指令,但是这个指令指向的地址是一个错误的,当在链接的时候才可以知道Data()函数的实体是在哪个 .obj 文件中。
在此程序中Data()函数的实体定义在template.cpp文件中,但是编译的时候template.obj中没有Data()函数实体的代码,链接的时候没有找到Data()函数的实体就出现错误。
原因:在C++中,模板需经过实例化后才能生成有效地代码,这样链接的时候才不会出错。