类模板
普通类的成员函数模板
不管是普通类, 还是类模板,他的成员函数都可以是函数模板, 被称为成员函数模板, 注意成员函数模板不能是虚函数
class A
{
public:
template<typename T>
void show(T i) const { cout << i << endl; }
}
A a;
a.show(4);
a.show(8.9);
a.show('a');
// 在编译期间, 编译器遇到这条语句的时候,这里的每一个调用都会生成一个实例.
类模板的成员函数模板
类模板的成员函数模板可以和类模板的参数不一样,但是在类外声明的时候必须要先定义类模板,然后在定义成员函数模板
template<typename T1>
class A
{
public:
template<typename T2>
A(T2 v1, T2 v2);
};
template<typename T1>
template<typename T2>
A<T1>::A(T2 v1, T2 v2)
{
cout << v1 << v2 << endl;
}
B<float> b(4, 5); // 编译器遇见这条语句的时候,才进行实例化
显示实例化 声明与定义
现在将模板类A封装到头文件test.h中
// test.h 头文件
template<typename T1>
class A
{
public:
template<typename T2>
A(T2 v1, T2 v2);
};
template<typename T1>
template<typename T2>
A<T1>::A(T2 v1, T2 v2)
{
cout << v1 << v2 << endl;
}
现在创建了test_1, test_2的cpp文件
// test_1.cpp
A<float> a(1, 3);
// test_2.cpp
A<float> a<56, 89>;
在这两个cpp文件中都有使用模板A, 当编译器遇见这些语句都会实例化一个A<float>, 如果当文件中定义了很多这种代码. 这会造成生成多个实例化的开销.为了避免这种开销,可以使用显示实例化.
在test_1顶部包含这条语句
// test_1.cpp
// 显示实例化中的实例化定义, 这种实例化定义只需要在一个cpp文件中写就行
template A<float>; // 编译器遇见这行语句会生成一个A<float>类
在test_2顶部包含这条语句
// test_2.cpp
// 其余文件都这么写
extern template A<float> // 显示实例化中的实例化声明
// 当编译器遇见上述语句, 编译器不会在生成A<float>类
函数模板同类模板也是一样的写法.