C++ 模板
江西理工 FangSH 2010-10-1
若一个程序的是对某种特定的数据类型进行处理,则可以交所处理的类型说明为参数,以便在其他数据类型的情况下使用.这就是模板的由来.模板是以一种完全通用的方法来设计函数或类而不必能预先说明使用的每个对象的类型.
模板可分为类模板(class template)和函数模板(function temlpate).
模板的语法
模板函数
template 类型形参表
返回类型 函数名(形参表)
{
函数定义体;
}
"类型形参表"可以包含基本数据类型,也可以包含类类型;类型形参要加前缀class.
且参数必须在"函数体中出现一次".对函数模板的说明和定义必须是全局作用域.模板不能被说明为类的成员函数. 模板类型不具有隐式的类型转换.
关于模板函数的使用用例子用说明更用具体些:
//
/*
* author : fsh
* date : 2010 5 12
* Note : 关于函数模板的练习.很基础的.但是可以知道
* 函数模板是怎么定义 怎么用的.
*/
#include "stdafx.h"
#include <iostream>
usingnamespace std;
class coord
{
int x, y;
public:
coord (int x1, int y1)
{
x = x1;
y = y1;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
intoperator< (coord & c);
};
int coord::operator< (coord & c) // 定义重载 "<"运算符
{
if (x < c.x)
{
if (y < c.y)
{
return1;
}
}
return0;
}
template <class obj>// 函数模板说明
obj & min(obj & o1, obj & o2);
int _tmain(int argc, _TCHAR* argv[])
{
coord c1(5, 11);
coord c2(6, 18);
coord c3 = min(c1, c2); // 利用重载"<"运算符比较min中的coord对象
cout <<"较小的坐标:("<< c3.getx() <<", "<<
c3.gety() <<")"<< endl;
double d1 =3.25;
double d2 =2.54;
cout <<"较小的数:"<< min(d1, d2) << endl;
// 利用标准"<" 运算符比较min中的double对象
system("pause");
return0;
}
template <class obj>
obj & min (obj & o1, obj & o2)
{
if (o1 < o2) // 如果函数被实例化为类类型,则对"<" 运算符进行重载
{ // 否则使用标准"<"运算符
return o1;
}
return o2;
}
模板类
template 类型形参表
class 类名
{
类说明体;
};
template 类型形参表
返回类型 类名 类型名表::成员函数1(形参表)
{
成员函数定义体;
}
返回类型 类名 类型名表::成员函数2(形参表)
{
成员函数定义体;
}
……
返回类型 类名 类型名表::成员函数n(形参表)
{
成员函数定义体;
}
这不是一个类,而是对一个类的描述。
同样的, 可以用例子来说明怎么样去使用
//
/* author : fsh
* date : 2010 5 12
* E-mail : fangshenghui@gmail.com
* Note : 模板类的一个很基础的例子.
* 大致一可以知道怎么定义模板类和使用模板类
*/
#include "stdafx.h"
#include <iostream>
usingnamespace std;
template <class T>
class array
{
int size;
T *aptr;
public:
array(int slots =1)
{
size = slots;
aptr =new T[slots]; // 为数组分配内在空间
}
void fill_array();
void disp_array();
~ array()
{
delete []aptr;
}
};
template <class T>
void array <T>::fill_array()
{
cout <<"(输入"<< size <<"个数)"<< endl;
for (int i=0; i<size; i++)
{
cout <<"第"<< i +1<<"个数据:";
cin >>aptr[i];
}
}
template <class T>
void array<T> ::disp_array()
{
for (int i=0; i<size; i++)
{
cout << aptr[i] <<"";
}
cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
array <char> ac(5); //
cout <<"填充一个字符数组";
ac.fill_array();
cout <<"数组的内容是:";
ac.disp_array();
array <double> ad(3);
cout <<"填充一个双精度数组:"<< endl;
ad.fill_array();
cout <<"数组的内容是:";
ad.disp_array();
system("pause");
return0;
}
要注意的地方:
1 与调用函数模板不同,使用类模板时,必须为模板形参显式指定实参。
2模板形参遵循常规名字屏蔽规则。
3 用作模板形参的名字不能在模板内部重用:这个限制还意味着模板形参的名字只能在同一模板形参表中使用一次。
{
typedf double T; //error
//...
return tmp;
}
4 像其他任意函数或类一样,对于模板可以只声吸而不定义。 同一声明和定义中,模板形参 的名字不必相同。
5 每个模板类型形参羰必须带上关键字classty或pename。而这两者的区别是旧的程序更有可能 只用关键字class.
template<class T> U calc(const U&, const U&);
template<class Type>
Type calc (const Type& a, const Type & b){/*……*/}
template <class T> T calc(const T &a, const T &b)
{
T tmp = a; //屏蔽全局变量
return tmp;
}