C++模板是支持参数化多态的工具,就是让类或者函数声明为一种通用类型,使得类中的某些成员变量或者成员函数的参数、返回值在实际使用中可以是任意类型。
使用模板的目的:可以让程序员编写与类型无关的代码,模板也是泛型编程(STL)的基础。
模板通常有两种形式:函数模板、类模板。
函数模板:针对仅参数类型不同的函数。
类模板:针对仅成员变量和成员函数类型不同的类。
模板声明或者定义:只能在全局、名字空间、类范围内,即不能在局部范围、函数内进行,如:不能在main函数中声明或者定义一个模板。
-
函数模板
参数类型不一样但是函数名及实现功能相同的函数。
1、可重载
2、可存在非模板参数
3、可使用默认参数
4、可显示调用传递类型
5、模板参数类型可以自定义
定义:
template <class 形参名,class 形参名, ..........>返回类型 函数名(参数列表)
{
//函数体
}
注意:class不是类,可用typename替换,用于声明一个模板参数类型,T表示任意类型,是一个占位符,表示模板参数类型,可以用于函数参数类型和返回类型。
-
示例
1、T一种任意类型,a与b类型必须为同一种任意类型。
2、T、T1为两种任意类型,a与b可以是不同类型,也可为同一种任意类型。
3、函数模板可存在非模板参数类型的参数,可重载(参数类型或者参数个数不同)
4、函数模板可存在默认参数,但不建议使用
5、存在显示调用,类型传递,将第一个参数转换为对应类型传递
将两个参数都转化为int类型传递
6、模板参数类型可以自定义
当T类型定义为int,返回类型为T时,结果并不为int,因为传递的参数为double类型,T发生了隐式类型转换int->double。
根据C++隐式类型转换规则,当两个不同类型的操作数进行运算时,会发生类型提升,int提升为了double。
-
类模板
template <class T,.........>
class A{
};
注意:类模板创建对象时必须显示调用,当类被当作类型使用时显示调用,当作名字时不用;类模板的友元函数必须是一个函数模板。
- 示例
-
友元函数模板
在类模板中声明,类模板外定义。
template <class T>
class A{
template <class C>
friend ostream& operator<<(ostream &os,const Arr<C>& obj);
};
template <class C>
ostream& operator<<(ostream& os,const Arr<C>& obj)
{
for(int i = 0;i < obj.len;i++)
os<<obj.addr[i]<<" ";
os<<endl;
return os;
}