泛型(Generic Programming)即是指具有在多种数据类型上皆可操作的含意。泛型编 程的代表作品 STL 是一种高效、泛型、可交互操作的软件组件。
泛型编程最初诞生于 C++中,目的是为了实现 C++的 STL(标准模板库)。其语言支持机制就是模板(Templates)。模板的精神其实很简单:参数化类型。换句话说, 把一个原本特定于某个类型的算法或类当中的类型信息抽掉,抽出来做成模板参数 T。
函数模板
所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。
函数重载实现的泛型
写n个函数,交换char类型、int类型变量的值。
原理
把数据类型作为参数。
语法格式
template<typename T>
template<class T>
template<typename 类型参数列表>
返回类型 函数模板名(函数参数列表){
函数模板定义体
}
template 是语义是模板的意思,尖括号中先写关键字 typename[类型名] 或是 class ,后 面跟一个类型 T[参数名],此类即是虚拟的类型。至于为什么用 T,用的人多了,也就是 T 了。
特点
- 调用函数时,数据类型不需要显示传递,系统自动检测
- 模板参数的个数可以一个或多个
- 形参列表中的参数不一定全部都是模板参数,也可以是基本数据类型0
实例
调用过程是这样的,先将函数模板实在化为函数,然后再发生函数调用。
函数模板只适用于函数的参数个数相同而类型不同,且函数体相同的情况。如果个数不同,则不能用函数模板。
函数模板与函数重载
普通函数会进行隐式的数据类型转换,函数模板不提供隐式的数据类型转换,必须是严格的匹配。
规则
1. 当函数模板和普通函数都符合调用时,优先选择普通函数
2. 若显示使用函数模板,则使用<> 类型列表
3. 如果 函数模板产生更好的匹配 使用函数模板
编译器对函数模板机制剖析
类模板
引入原因
减少代码重用
含义
类模板的意思是,按不同的方式重复使用相同的代码。
一个类模板(也称为类属类或类生成类)允许用户定义为类定义的一种模式,是的类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能够取任意类型【包括系统预定义的和用户自定义的】
概念
类模板
是一个类型参数化的样板,是一组类模板的集合
有两个或多个类,其功能是相同的,仅仅是数据类型不同,所以将类中的类型进行泛化。
模板类
是某个类模板的一个实例
声明
template <模板参数表>
class 类名 {
类成员声明
}
如果需要在类模板之外定义其成员函数,则要采用
template <模板参数表> 类型名 类名<T>::函数名(参数表)
实例化对象
类名<类型> 对象名;
数组类--属于直接访问群体
群体的概念
有多个数据元素组成的集合体。群体可以分为两大类:线性群体和非线性群体。线性群体 中的元素按位置排列有序,可以区分为第一个元素、第二个元素等。其元素与其位置的关系是对应的,在线性群体中按照访问方法不同,我们可以将其分为直接访问、顺序访问和索引访问 。非线性群体不用位置顺序来标识元素。
静态数组
是具有固定元素个数的群体,其中元素可以通过下标访问,其大小在编译时就已经确定,在运行过程中无法修改;
动态数组
有一系列位置连续的任意数量的相同类型的元素组成,其元素个数在程序运行时改变。
动态数组类的模板
Array类模板 //Array.h
简单的模板类
模板类的派生
类模板实现
函数体写在类中
函数体写在类外(在一个cpp中)
模板类不要轻易使用友元函数。
函数体写在类外(在.h和.cpp中)
由于二次编译,模板类在.h在第一次编译之后,并没有最终确定类的具体实现,只是编译器的词法校验和分析。在第二次确定类的具体实现后,是在.hpp文件生成的最后的具体类,所以main函数需要引入.hpp文件。
综上:引入hpp文件一说也是曲线救国之计,所以实现模板方法建议在同一个文件.h中完成