数据类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的参数自动确定数据类型。这就是数据类型参数化。
函数模板
所谓函数模板,实际上是建立一个通用函数,其返回值类型和形参类型不具体指定,用一个虚拟的类型来代替(实际上是用一个标识符来占位)。这个通用函数就称为函数模板(Function Template)。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会用实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
定义模板函数的语法为:
template<typename 数据类型参数,typename 数据类型参数,...> 返回值类型 函数名(形参列表){
//TODO:
//在函数体中可以使用数据类型参数
}
eg:
template <typename T> T sum(T a, T b){
T temp = a + b;
return temp;
}
模板类
假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数、小数和字符串,例如:
x = 10、y = 10
x = 12.88、y = 129.65
x = "东京180度"、y = "北纬210度"
坐标 x 和 y 的数据类型不确定,借助模板类,就可以将数据类型参数化,否则就要定义多个类。
这个时候就可以使用模板类,请看下面的代码:
template <typename T1,typename T2> //这里不能有分号
class Point{
private:
T1 x;
T2 y;
public:
Point(T1 _x, T2 _y): x(_x),y(_y){}
T1 getX();
void setX(T1 x);
T2 getY();
void setY(T2 y);
};
上面是类的声明,还需要在类外定义成员函数。在类外定义成员函数时仍然需要带上模板头,语法为:
template<类型参数列表> 函数返回值类型 类名<类型参数列表>::函数名(参数列表){
//TODO:
}
template<typename T1,typename T2>
T1 Point<T1 , T2>::getX(){
return x;
}
template<typename T1,typename T2>
void Point<T1 , T2>::setX(T1 x){
this->x = x;
}
template<typename T1,typename T2>
T2 Point<T1 , T2>::getY(){
return y;
}
template<typename T1,typename T2>
void Point<T1 , T2>::setY(T2 y){
this->y = y;
}