【C/C++】【模板和泛型】类模板
概述
- 用类模板实例化一个特定的类;
- 编译器不能为类模板推断模板参数,为了使用类模板,必须在模板名后用<>来提供额外的信息;
- 同一套代码,可以应付不同的数据类型;
类模板定义
-
格式
template <typename T, ...> class name { }
-
实例化类模板的时候,必须要有类的全部信息,包括类模板中成员函数的函数体;
类模板的成员函数
- 类模板成员函数可以写在类模板定义中,这些成员函数被隐式声明为内联函数;
- 把成员函数的函数体(函数具体实现)放在类模板的定义中;
- 类模板一旦被实例化之后,那么这个模板的每个实例都会有自己版本的成员函数;所以,类模板的成员函数具有和这个类模板相同的模板参数;类模板的成员函数有模板参数;
- 如果把类模板成员函数的定义(函数体)写在类模板定义的外边;那么这个成员函数的模板参数就体现出来了
- 定义在类模板之外的成员函数必须以关键字template开始,后边接类模板参数列表,同时在类名后面用尖括号<>把模板参数列表里面的所有模板参数名列出来,如果是多个模板参数,用逗号分隔;
- 一个类模板可能有很多成员函数,但是当实例化模板之后,成员函数只有在被使用的时候才会被实例化;没有使用到就不会被实例化;
//vector实现
template<typename T>
class my_vector
{
public:
typedef T* iter; //迭代器
public:
my_vector();
//在类模板内部使用模板名并不需要提供模板参数;也可以加
my_vector& operator=(const my_vector&);
//my_vector<T>& operator=(const my_vector<T>&);
iter begin();
iter end();
void func();
};
template<typename T>
void my_vector<T>::func()
{
return;
}
//构造函数
template<typename T>
my_vector<T>::my_vector()
{
}
template<typename T>
my_vector<T>& my_vector<T>::operator=(const my_vector<T>&)
{
return *this;
}
int main()
{
my_vector<int> i_vec;
return 0;
}
非类型模板参数
- 浮点数不能做非类型模板参数;
- 类类型一般也不允许做非类型模板参数;
#include <iostream>
using namespace std;
template<typename T, int size = 10>
class Arr
{
private:
T arr[size];
public:
void func();
};
template<typename T, int size>
void Arr<T, size>::func()
{
cout << size << endl;
return;
}
int main()
{
Arr<int, 100> a;
Arr<int> b;
return 0;
}
总结
- 类模板不能推断模板参数
- 类模板的成员函数
- 哪些类型不能做类模板的非模板类型参数
知识的价值不在于占有,而在于使用