泛型程序设计
算法实现时不指定具体要操作的数据的类型。适用于多种数据结构。
函数模板
Template <class 类型参数1,class类型参数2,…..>
返回值类型 模板名(形参表)
{
函数体;
}
函数模板可以重载,只要它们的形参表不同即可。
C++编译器遵循以下优先顺序:
- 先找参数完全匹配的普通函数(非由模板实例化而得的函数)
- 再找参数完全匹配的模板函数
- 再找实参经过自动类型转换后能匹配的普通函数
- 上面的都不符合则报错。
可以在函数模板中使用多个类型参数,可以避免二义性。
#include <iostream> using namespace std; void M(int &a, int &b) { cout << "M1 is called" << endl; } template <class T> void M(T &a, T &b) { cout << "M2 is called" << endl; } template <class T1, class T2> void M(T1 &a, T2 &b) { cout << "M3 is called" << endl; } int main() { int a=0, b=0; double c = 0, d = 0; int e = 0; float f = 0; M(a, b); M(c, d); M(e, f); return 0; }
运行结果:
类模板
- 在定义类的时候给它一个/多个参数
- 这个一个/多个参数表示不同的数据类型
调用类模板时,指定参数,由编译系统根据参数提供的数据类型自动产生相应的模板类。
类模板的定义
Template <类型参数表>
Class 类模板名
{
成员函数和成员变量
}
类型参数表的写法就是:
Class 类型参数1,class 类型参数2,….
- 类模板里的成员函数,如在类模板外面定义时,
Template<类型参数表>
返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)
{
…..
}
用类模板定义对象的写法如下:
类模板名<真实类型参数表> 对象名(构造函数实际参数表);
如果类模板有无参构造函数,那么也可以只写:
类模板名 <真实类型参数表>对象名;
使用类模板声明对象
编译器由类模板生成类的过程叫类模板的实例化
- 编译器自动用具体的数据类型替换模板中的类型参数,生成模板类的代码
- 由类模板实例化得到的类叫模板类。为类型参数指定的数据类型不同,得到的模板类不同。
同一个类模板的两个模板类是不兼容的
Pair<string,int> *p;
Pair<string,double> a;
p=&a//wrong;
类模板与非类型参数
类模板的参数声明中可以包括非类型参数
Template<class T, int elementsNumber >
- 非类型参数:用来说明类模板中的属性
- 类型参数:用来说明类模板中的属性类型,成员操作的参数类型和返回值类型。
cArray<int, 50> 和cArray<int , 40>完全是两个类,这两个类的对象之间不能互相赋值。
类模板与继承
- 类模板派生出类模板,派生类模板的类型参数名列表中应包含基类模板的参数
- 模板类(即类模板中类型/非类型参数实例化后的类)派生出类模板
- 普通类派生出类模板
- 模板类派生出普通类
类模板派生出类模板
Template <class T1, class T2>
Class A
{
T1 v1;T2 v2;
}
Template <class T1, class T2>
Class B:public A<T2, T1>
{
T1 v3;T2 v4;
}
Template<class T>
Class C:public B<T,T>
{
T v5;
}
模板类派生出类模板
Template <class T1, class T2>
Class A{T1 v1; T2 v2};
Template <class T>
Class B :public A<int, double>{T v};
普通类派生出类模板
Class A
{
int m;
}
Template <class T>
Class B:public A
{
T v;
}
模板类派生出普通类
Template <class T1, class T2>
Class A{T1 v1; T2 v2};
Class B :public A<int ,double>
{
int v;
}
类模板实例:
#include <iostream> #include <string> using namespace std; template <class T1, class T2> class Pair { public: T1 key; T2 value; Pair(T1 key, T2 value) :key(key), value(value) {} bool operator <(const Pair<T1, T2> &p) const; }; template <class T1, class T2> bool Pair<T1,T2>::operator<(const Pair<T1, T2> &P) const { return (value < P.value); } int main() { Pair<string, int> student("Tom", 19); cout << student.key << " " << student.value << endl; return 0; }
参考链接:
https://www.coursera.org/learn/cpp-chengxu-sheji