非模板模型:包括普通函数,普通类;
在调用普通函数时,编译器只需要看到函数的声明。
在定义类对象时,编译器只需要看到类的定义,成员函数的定义不是必须存在的。
所以:将类的定义和函数的申明放在头文件中,类成员函数的定义,普通函数的定义放在源文件中。
模板模型:包括模板函数,模板类;
在调用模板函数或类的模板成员函数时,编译器需要知道函数的定义,然而这些代码通常放在源文件中。
在进行类模板实例化的时候,编译器必须能够访问定义模板的源代码。
编译模板代码有两种模型:包含编译模型 分别编译模型
这两种模型都是将类定义和函数声明放在头文件中,函数定义和成员定义放在源文件中。
包含编译模型:编译器必须看到用到的模板的定义。即实现了头文件和实现文件的分离,又实现了编译器在编译模板的时候能看见定义。 VS2008支持
/*test.h*/
#ifndef _TEST_
#define _TEST_
#include "test.cpp"
template <typename T> int compare(const T&, const T&);
#endif
/*test.cpp*/
template< typename T> int compare(const T &v1, const T &v2) {
if(v1 > v2)
return -1;
else if(v2 > v1)
return 1;
else
return 0;
}
分别编译模型
:VS2008不支持
对于普通模板函数,在定义函数之前加入export,声明则不需要加入export。如某源文件中定义:
template<class T> T sum(T t1, T t2);
对于类模板,函数声明在类中,定义在源文件中,所以头文件中的类定义中没有使用export,而应该在源文件中加入export