Java中的泛型编程可以极大的提升编程的效率,比如在android中查找一个控件的ID:标准写法为:
TextView tv_text = (TextView)findViewById(R.id.tv_text);
或者:
ImageView iv_img = (ImageView)findViewById(R.id.iv_img);
因为同为查询控件ID,所以上面的写法可以采用泛型编程精简为:
protected finalT getView(int id) { return (T) findViewById(id);}
这样在下次使用的时候就可以写成这样:
TextView tv_text = getView(R.id.tv_text);
C++中也有类似的东西,不过名字变了,叫模板(template)。
一.函数模板
例:交换两个相同类型变量的值
原始写法:
//交换 int 变量的值void Swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp;}//交换 float 变量的值void Swap(float *a, float *b){ float temp = *a; *a = *b; *b = temp;}//交换 char 变量的值void Swap(char *a, char *b){ char temp = *a; *a = *b; *b = temp;}//交换 bool 变量的值void Swap(bool *a, bool *b){ char temp = *a; *a = *b; *b = temp;}
使用模板后的写法:
#includeusing namespace std;template void Swap(T *a, T *b){ T temp = *a; *a = *b; *b = temp;}int main(){ //交换 int 变量的值 int n1 = 100, n2 = 200; Swap(&n1, &n2); cout< <<", "< <
修改成引用:
#includeusing namespace std;template void Swap(T &a, T &b){ T temp = a; a = b; b = temp;}int main(){ //交换 int 变量的值 int n1 = 100, n2 = 200; Swap(n1, n2); cout< <<", "< <
例:求三个数最大值:
#includeusing namespace std;//声明函数模板template T max(T a, T b, T c);int main( ){ //求三个整数的最大值 int i1, i2, i3, i_max; cin >> i1 >> i2 >> i3; i_max = max(i1,i2,i3); cout << "i_max=" << i_max << endl; //求三个浮点数的最大值 double d1, d2, d3, d_max; cin >> d1 >> d2 >> d3; d_max = max(d1,d2,d3); cout << "d_max=" << d_max << endl; //求三个长整型数的最大值 long g1, g2, g3, g_max; cin >> g1 >> g2 >> g3; g_max = max(g1,g2,g3); cout << "g_max=" << g_max << endl; return 0;}//定义函数模板template //模板头,这里不能有分号T max(T a, T b, T c){ //函数头 T max_num = a; if(b > max_num) max_num = b; if(c > max_num) max_num = c; return max_num;}
运行结果:
12 34 100
i_max=10073.234 90.2 878.23d_max=878.23344 900 1000g_max=1000总结一下,函数模板的基本语法为:
template返回值类型 函数名(形参列表){ //在函数体中可以使用类型参数}
二.类模板
类模板的声明与函数模板的声明类似:
templateclass 类名{ //TODO:};
示例代码:
#includeusing namespace std;template //这里不能有分号class Point{public: Point(T1 x, T2 y): m_x(x), m_y(y){ }public: T1 getX() const; //获取x坐标 void setX(T1 x); //设置x坐标 T2 getY() const; //获取y坐标 void setY(T2 y); //设置y坐标private: T1 m_x; //x坐标 T2 m_y; //y坐标};template //模板头T1 Point ::getX() const /*函数头*/ { return m_x;}template void Point ::setX(T1 x){ m_x = x;}template T2 Point ::getY() const{ return m_y;}template void Point ::setY(T2 y){ m_y = y;}int main(){ Point p1(10, 20); cout<<"x="< <<", y="< < p2(10, "东京180度"); cout<<"x="< <<", y="< < *p3 = new Point ("东京180度", "北纬210度"); cout<<"x="< getX()<<", y="< getY()<
输出结果:
x=10, y=20
x=10, y=东京180度x=东京180度, y=北纬210度注意:
1.在对类模板的成员函数进行定义时,除了 template 关键字后面要指明类型参数,类名 Point 后面也要带上类型参数,只是不加 typename 关键字了
2.类模板在实例化时必须显式地指明数据类型,赋值号两边也要指明具体的数据类型,且要保持一致。