为什么须要模板?
我们已经学过重载(Overloading),对重载函数而言,C++ 通过函数參数(參数个数、參数类型)的正确匹配来调用重载函数。比如。为求两个数的最大值,我们定义 max () 函数须要对不同的数据类型分别定义不同重载(Overload)版本号。
//函数1
int max(int x, int y);
{
return(x>y)?x:y ;
}
//函数2
float max( float x, float y)
{
return (x>y)?
x:y ;
}
//函数3
double max(double x, double y)
{
return (c>y)?x:y ;
}
如今。我们再又一次审视上述的 max() 函数,它们都具有相同的功能,即求两个数的最大值,是否能仅仅写一套代码解决问题呢?这样就会避免因重载函数定义不全面而带来的调用错误(如。我们分别定义了 char a,b; 那么在运行 max(a,b) 时 程序就会出错,由于我们未定义char 类型的重载版本号)。
相同的,对于类而言,也存在相同的问题(基本上是反复性的工作):
//对两个整数作比較
class Compare_int
{
public:
Compare(int a,int b){x=a;y=b;}
int max( ) {return(x>y)?x:y;}
int min( ) {return(x<y)?x:y;}
private:
int x,y;
};
//对两个浮点数作比較
class Compare_float
{
public:
Compare(float a,float b) {x=a;y=b;}
float max( ) {return(x>y)?x:y;}
float min( ) {return(x<y)?
x:y;}
private:
float x,y;
}
为解决上述问题 C++ 引入模板机制:模板就是实现代码重用机制的一种工具,它能够实现类型參数化,即把类型定义为參数。 从而实现了真正的代码可重用性。模版能够分为两类。一个是函数模版。另外一个是类模版。
函数模板
函数模板的一般形式例如以下:
template <class 形參名, class 形參名, ……> 返回类型 函数名(形參表)
{
//函数定义体
}
当中 template 和 class 是keyword,class 能够用 typename 取代,在这里 typename 和 class 没差别。<> 括号里的參数叫模板形參。模板形參和函数形參非常相像。模板形參不能为空。
一但声明了类模板,函数中使用内置类型的地方都能够使用模板形參名来声明。
模板形參须要调用该模板函数时提供的模板实參来初始化模板形參,一旦编译器确定了实际的模板实參类型就称他实例化了函数模板的一个实例。
template <class T> void swap(T& a, T& b)
{
//……
}
当调用这种模板函数时类型 T 就会被被调用时的类型所取代,比方 swap(a,b) 当中 a 和 b 是 int 型,这时模板函数 swap 中的形參 T 就会被 int 所取代,模板函数就变为 swap(int &a, int &b)。而当 swap(c,d) 当中 c 和 d 是 double 类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。
演示样例代码例如以下:
#include <iostream>
using std::cout;
using std::endl;
//声明一个函数模版,用来比較输入的两个同样数据类型的參数的大小,
//class也能够被typename取代。
//T能够被不论什么字母或者数字取代。
//template <typename T>
template <class T> T max(T x,T y)
{
return(x>y)?x:y;
}
int main()
{
int a=2, b=10;
cout<< "较大整数:"<<max(a, b)<<endl;
double m=1.5, n=5.6;
cout<< "较大实数:"<<max(m, n)<<endl;
return 0;
}
执行结果例如以下:
类模板
类模板的一般形式例如以下:
template <class 形參名, class 形參名, ……> class 类名
{
//类定义...
};
一但声明了类模板就能够用类模板的形參名声明类中的成员变量和成员函数,即能够在类中使用内置类型的地方都能够使用模板形參名来声明。比方:
template <class T> class A
{
public:
T a;
T b;
T hy(T c, T &d);
};
在类 A 中声明了两个类型为T的成员变量 a 和 b。还声明了一个返回类型为 T 带两个參数类型为 T 的函数 hy。
类模板对象的创建:比方一个模板类 A,则使用类模板创建对象的方法为 A<int> m;在类 A 后面跟上一个 <> 尖括号并在里面填上对应的类型。这种话类 A 中凡是用到模板形參的地方都会被 int 所取代。
当类模板有两个模板形參时创建对象的方法为 A<int, double> m;类型之间用逗号隔开。
在类模板外部定义成员函数的方法为:
template<模板形參列表> 函数返回类型 类名<模板形參名>::函数名(參数列表){函数体}
比方有两个模板形參 T1。T2 的类 A 中含有一个 void h() 函数。则定义该函数的语法为:
template<class T1, class T2> class A
{
public:
void h();
};
template<class T1,class T2> void A<T1,T2>::h()
{
// ……
}
注意:模板的声明或定义仅仅能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比方不能在 main() 函数中声明或定义一个模板。
演示样例代码例如以下:
#include <iostream>
using namespace std;
template <class numtype> class Compare //类模板
{
public:
//Compare(numtype a,numtype b){x=a;y=b;}
Compare(numtype a,numtype b);
numtype max(){return (x>y)?x:y;}
numtype min(){return (x<y)?x:y;}
private:
numtype x,y;
};
template <class numtype> Compare<numtype>::Compare(numtype a,numtype b)
{
x=a;
y=b;
}
int main( )
{
Compare<int>cmp1(3,7); //定义对象cmp1,用于两个整数的比較
cout << cmp1.max() << " is the Maximum" << endl;
cout << cmp1.min() << " is the Minimum" << endl << endl;
Compare<float> cmp2(45.78,93.6); //定义对象cmp2。用于两个浮点数的比較
cout << cmp2.max() << " is the Maximum" <<endl;
cout << cmp2.min() << " is the Minimum" <<endl<<endl;
Compare<char> cmp3('a', 'A'); //定义对象cmp3。用于两个字符的比較
cout << cmp3.max() << " is the Maximum" <<endl;
cout << cmp3.min() << " is the Minimum" <<endl;
return 0;
}
执行结果例如以下:
參考资料: