容器 container

功能:包含一定数据或者对象,没有本质定义
多次重复的使用某些代码,对象是不同的数据类型,我们称其为 polymorphism 或者 polymorphic
因此我们需要使用一个叫做 template 的东西

模板 template

每一个模板只能使用一个数据类型的数据,但是模板可以有多种数据类型的应用。
这个的处理是将类型名称作为编译过程的一个参数,同时这是一个参数泛化的一个实现
实现代码如下:

1
2
3
4
5
template <class T>  // 前面我们学过了,class 就是一种 ADT,或者说 c++ 就是将 type 认作是 ADT 的一种
class List{
// 在这里面我们可以用 T 表示任何数据类型
void foo(T a); // 但是 declaration 里并不需要 List<T>
};

接下来我们需要讨论的就是每一个成员函数的定义了,如何实现?

1
2
3
4
// 每一个成员函数前面 (如果该函数用到了 template) 都要写 template 这一行
template <class T>
void List<T>::foo(T a){
}

当然你会想问,如果有一个构造函数,我们要不要加 <T> ? 答案是不需要:

1
2
List<T>::List(){};
List<T>::~List();
注:在早期c++标准中只有 template <class T> 的写法,但是后来开发者认为这里的写法太容易混淆,于是诞生了 template <typename T> 的写法,现在这个写法取决于团队(个人)写作风格

局限性

由于template 的定义域会局限在某一份文件中,因此我们需要将函数的实现 (implementation) 转移到这个头文件中来,事实上头文件是具有容纳实现代码的功能的
由于C++的模板是在编译时实例化的,编译器需要在编译时看到完整的模板定义,而不仅仅是声明。这意味着模板的定义(包括所有模板函数和模板类的成员函数的定义)通常需要放在头文件中,或者至少在编译之前对编译器可见。