按照WHAT, WHY, HOW的思路学习。
1. 什么是C++模板?
答:模板就是实现代码重用机制的一种工具。它实现了将类型参数化,就是将类型定义为参数,实现了真正的代码可重用性。模板分为两大类:函数模板和类模板。由于类模板包含类型参数,所以类模板又称作参数化的类。如果说类是对象的抽象,抽象是类的实例;那么可以说类模板是类的抽象,而类是类模板的实例。利用类模板可以建立各种数据类型的类。
2.为什么要引入模板机制呢?
答:为了实现代码重用,避免或者减少做重复性的工作,以及避免因重载函数定义不全面引起的调用错误等。
3.如何使用(实现)?
(1)函数模板的形式:
说明:①
template 是声明模板的关键字;class可以被typename代替;T是虚拟类型参数,可以被任何字母,字符串或者数字代替。
②当模板类和重载函数一起使用时,会首先考虑重载函数,其次是模板类,再没有的话会考虑类型转换(可能会不精确)。
测试实例:
(2)模板类
举例:
比如在未使用模板类之前:要对两个整数作比较:
如果你又想对double类型的数据作比较呢,就得重新定义一个新的类来实现:
这样就会比较麻烦。做的重复性的工作很多,使用了模板机制以后就可以减少这些问题。
可以声明一个通用的类模板,它可以有一个或多个虚拟的类型参数,比如对上面两个类可以综合写出以下的类模板:
将这个类模板和前面的两个类作比较,会发现:
1>多出了一行 template < class numtype > 即声明类模板时要先加上一行template
2>原有的类型名int换成虚拟类型参数名numtype.这样在建立类对象时,如果将实际类型指定为int型,编译系统就会用int取代所有的numtype,如果指定为double型,就用double取代所有的numtype。这样就能实现“一类多用”。
在声明了一个类模板之后,如何使用它,将它变成一个实际的类呢?
回想一般的定义一个对象的方法:
用类模板来定义对象的方法和上面的方法类似,但是不能直接那么写。Compare是一个类模板名,而不是一个具体类;numtype是一个虚拟类型,而不是一个具体类型;因此无法用它去定义一个对象。而必须用实际的类型名取代虚拟类型,具体做法:
即在类模板名之后的尖括号内指定实际的类型名,在进行编译时,编译系统就用double取代类模板中的类型参数numtype,这样就把类模板具体化了,或者说实例化了。这时Compare就相当于前面介绍的Compare_double类。
注意:前面的类模板中的成员函数是在类模板内定义的,如果改为在类模板外定义,则不能使用一般的定义类成员函数的方法:
而应该写成类模板的形式:
总结上面的学习,可以这样声明和使用类模板:
1)先写出一个实际的类。其语义明确,含义清楚。一般不会错。
2)将该类中准备改变的类型名(比如Int要改为char、double等)改为一个自己指定的虚拟类型名(比如上面例子中的numtype)。
3)在类的声明前加一行:
template 。
4)使用类模板定义对象时使用如下形式:
5)如果在类模板之外定义成员函数,应该写成类模板形式:
注意:
1)类模板的类型参数可以有一个或者多个,每个类型前面都必须加class,如:
在定义对象名时,分别带入实际的类型名,比如:
2)和使用普通类一样,在使用模板类时一定要注意其作用域。
3)模板也可以有层次,一个类模板可以作为基类,可以派生出派生模板类。
参考: http://blog.csdn.net/hackbuteer1/article/details/6735704
http://see.xidian.edu.cn/cpp/biancheng/view/213.html
1. 什么是C++模板?
答:模板就是实现代码重用机制的一种工具。它实现了将类型参数化,就是将类型定义为参数,实现了真正的代码可重用性。模板分为两大类:函数模板和类模板。由于类模板包含类型参数,所以类模板又称作参数化的类。如果说类是对象的抽象,抽象是类的实例;那么可以说类模板是类的抽象,而类是类模板的实例。利用类模板可以建立各种数据类型的类。
2.为什么要引入模板机制呢?
答:为了实现代码重用,避免或者减少做重复性的工作,以及避免因重载函数定义不全面引起的调用错误等。
3.如何使用(实现)?
(1)函数模板的形式:
点击(此处)折叠或打开
- Template <class或者也可以用typename T>//函数(类)模板的声明
-
- 返回类型 函数名(形参表)//函数模板的定义/实现
- {
- //函数定义体
- }
②当模板类和重载函数一起使用时,会首先考虑重载函数,其次是模板类,再没有的话会考虑类型转换(可能会不精确)。
测试实例:
点击(此处)折叠或打开
- //main.cpp
- #include <iostream>
-
- using std::cout;
- using std::endl;
- //声明一个函数模板,用来比较输入的两个相同数据类型参数的大小,class也可以被typename代替
- //T可以被任意字母或者数字代替
- template <typename T>
- T max(T x, T y)
- {
- return (x > y) ? x : y;
- }
-
- int main()
- {
- int n1 = 2, n2 = 10;
- float d1 = 1.5, d2 = 5.6;
-
- cout << "Integer result is:" << max(n1, n2) << endl;
- cout << "Real result is:" << max(d1, d2) << endl;
-
- return 0;
- }
点击(此处)折叠或打开
- template <class 类型参数名>//声明模板类
- class 具体类型参数名 //定义具体类
- {
- //...
- }
比如在未使用模板类之前:要对两个整数作比较:
点击(此处)折叠或打开
- class Compare_integer
- {
- 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_double
- {
- public :
- Compare(double a,double b)
- {
- x=a;
- y=b;
- }
- double max()
- {
- return (x>y)?x:y;
- }
- double min()
- {
- return (x<y)?x:y;
- }
- private :
- double x,y;
- }
点击(此处)折叠或打开
- template <class numtype>
- class Compare
- {
- public :
- Compare(numtype a,numtype b)
- {
- x=a;
- y=b;
- }
- numtype max()
- {
- return (x>y)?x:y;
- }
- numtype min()
- {
- return (x<y)?x:y;
- }
- private :
- numtype x,y;
- }
1>多出了一行 template < class numtype > 即声明类模板时要先加上一行template
2>原有的类型名int换成虚拟类型参数名numtype.这样在建立类对象时,如果将实际类型指定为int型,编译系统就会用int取代所有的numtype,如果指定为double型,就用double取代所有的numtype。这样就能实现“一类多用”。
在声明了一个类模板之后,如何使用它,将它变成一个实际的类呢?
回想一般的定义一个对象的方法:
点击(此处)折叠或打开
- Compare_double cmp(2.3, 5.8);//Compare_double是已经声明的类
点击(此处)折叠或打开
- Compare<double> cmp(2.3, 5.8);
注意:前面的类模板中的成员函数是在类模板内定义的,如果改为在类模板外定义,则不能使用一般的定义类成员函数的方法:
点击(此处)折叠或打开
- numtype Compare::max(){...}
点击(此处)折叠或打开
- template <class numtype>
- numtype Compare<numtype>::max()
- {
- return (x>y)?x:y;
- }
1)先写出一个实际的类。其语义明确,含义清楚。一般不会错。
2)将该类中准备改变的类型名(比如Int要改为char、double等)改为一个自己指定的虚拟类型名(比如上面例子中的numtype)。
3)在类的声明前加一行:
template 。
4)使用类模板定义对象时使用如下形式:
点击(此处)折叠或打开
- 类模板名<实际类型名> 对象名;
- 类模板名<实际类型名> 对象名(实参列表);
点击(此处)折叠或打开
- template <class 虚拟参数类型>
- 函数类型 类模板名<虚拟参数类型>::成员函数名(函数形参列表){...}
注意:
1)类模板的类型参数可以有一个或者多个,每个类型前面都必须加class,如:
点击(此处)折叠或打开
- template <class T1,class T2>
- class someclass
- {…};
点击(此处)折叠或打开
- someclass<int, char> Obj;
3)模板也可以有层次,一个类模板可以作为基类,可以派生出派生模板类。
参考: http://blog.csdn.net/hackbuteer1/article/details/6735704
http://see.xidian.edu.cn/cpp/biancheng/view/213.html