C++作为兼容C语言却又更强大的语言来说,C++真正强大且区别于C的地方就是泛型编程了。
在C++中,模板是泛型编程的基础,模板是创建类和函数的蓝图。
假设要写一个函数比较两个值,指出第一个值是小于、等于还是大于第二个值。我们可以用函数重载:
int compare( const int &a, const int &b){
if(a == b){
return 0;
}
return a>b?1:-1;
}
int compare( const double &a, const double &b){
if(a == b){
return 0;
}
return a>b?1:-1;
}
这两个函数基本相同,唯一不同的是参数,但是这种太麻烦了,也容易出错,并且有时候根本不知道比较的到底是哪个类型。
定义一个函数模板,就是一个独立类型的函数。如下:
template < typename T >
int compare( T &a, T &b ){
if( a == b ){
return 0;
}
return a>b?1:-1;
}
模板的定义以关键字template开始,后面接模板参数( template parameter list ),模板形参表是用尖括号括起来的一个或多个模板形参( template parameter ),形参之间用逗号分割。
使用函数模板时,编译器推断是哪个模板实参( template argument )绑定到模板形参。一旦编译器确定了实际的模板实参,就称他实例化( instantiate )了一函数模板的实例。
int main(){
cout << compare(0, 1) <cout << compare("abc", "bcd") <return 0;
}
编译器把实例化compare
的两个不同版本,编译器用Int代替T 创建第一个,用string替换T创建第二个。
函数模板可以用与非模板函数一样的方式声明为inline
。说明符放在模板形参表之后、返回类型之前,不能放在关键字template
之前。
template < typename T > inline T min(const T&, const T&);
我们定义类模版的时候同函数模板一样。
例如我们定义一个Point
类,可能是2d(x和y)的,可能是3d(x,y和z)的,所以需要类模版。第一种是定义3d的Point:
template < class type >
class Point3d
{
public:
Point3d( type x = 0.0, type y = 0.0, type z = 0.0)
: _x(x), _y(y), _z(z) {}
type x(){
return _x;
}
void x( type xval ){
_x = xval;
}
private:
type _x;
type _y;
type _z;
};
或者我们把参数个数也变成可变的:
template < class type, int dim >
class Point{
public:
Point();
Point(type coords[dim]){
for (int index = 0; index < dim; index++) {
_coords[index] = coords[index];
}
}
type& operator[] (int index){
assert(index < dim && index >= 0);
return _coords[index];
}
type operator[] ( int index ) const{
assert(index < dim && index >= 0);
return _coords[index];
}
private:
type _coords[dim];
};
这样就可以了。使用的时候直接声明就可以了。
Point< int, 3 > point;
以上就是泛型编程的基础了。