模板是C++提供进行编程的一种类书工具。所以在看本文以前请先了解一下C++类书的概念及相关的知识。 1.模板的概念: 模办是实现类属机制的一种工具,它的功能非常强,它是无约束类属机制和约束类属机制的集合。它可以让用户构造模板函数。 模板,对象, 函数之间的关系见下图:
2.函数模板与模板函数: 先见下例: #include <iostream.h> template<class T> //模板声明 T max(T x,T y) //定义模板 main() 上面的这个程序虽然只是实现一个很简单的比较大小的问题, 但如果不用模板, 而用我们以前的方法,由于参数类型和返回值类型不同将需要三个函数来实现, 这样是十分麻烦的。模板成功的解决了这个问题, 程序中生成了三个模板函数,其中max(i,j)用模板实参int将类型实参数T进行了实例化;max(x1,x1)用模板实参float将类型参数T进行了实例化;max(y1,y2)用模板实参double将类型参数T进行了实例化。 从上面的例子我们可以看出, 函数模板提供了一类函数的抽象, 它以任意类型T为参数及函数返回值。由一个函数模板产生的函数称为模板函数,它是函数模板的具体实例。 函数模板和模板函数的关系图:
要提醒大家注意的一点是:虽然模板参数T可以实例化成各种类型, 但是采用模板参数T的各种参数T的各参数之间必须保持完全一致的类型。例如: T max(T x,T y) void func(int i, char c, float) 解决上面的问题就需要引入一个型的概念—重载, 既可以用非模板函数重载一个同名的函数模板。 重载有两种表述方式: 1.利用函数模板的函数体 使用次方法是必须注意各模板参数的实参类型必须一致。例如: int max(int,int) 2.重新定义函数体 对于要重新定义函数体的重载函数, 所带参数的类型可以随意, 就象一般的重载函数一样定义。 定义重载函数特别要注意避免产生预期的和非预期的二义性。例如: int max(int, int); char max(int x,char y)
(1)寻找一个参数完全匹配的函数,如果找到了就调用它。 (2)在(1)失败后, 寻找一个函数模板,使其实例化, 产生一个匹配的模板函数, 若找到了,就调用它。 (3)在(1)(2)均失败后,再试一试低一级的对函数的重载方法,例如通过类型转换可产生参数匹配等, 若找到了,就调用它。 (4)若(1)(2)(3)均失败,则这是一个错误的调用。 3.类模板与模板类 类模板与模板类的概念 一个类模板可以让用户为类定义一种模式, 使得类中的某些数据成员,某些成员函数的参数,某些成员函数的返回值,能取任意类型。 定义一个类模板,一般由两方面的内容: (1)首先要定义类,其格式为: template<class T> //声明一个模板 class name name为类名,在类定义体中如采用数据类型的成员, 函数参数的前面需加上T。例如: template<class T> class vector (2)在类定义体外定义成员函数时,若此成员函数中有模板参数存在, 则需在函数体外进行模板声明, 并且在函数名前的类名后缀上“<T>”.例如: template<class T> vector<T>::vector(int i) template<class T> T&vector<T>::operator[](int i) 类模板的使用 类模板的使用实际上是将类模板实例化成一个具体的类, 它的格式为: 类名<实际的类型> main() 类模板和模板类之间的关系, 如图:
类模板使用需要注意的几点: (1)在每个模板定义之前,不管是类模板还是函数模板, 都需要在前面加上模板声明: template<class T> (2)类模板和结构模板在使用时, 必须在名字后面缀上模板参数<T>,如:list<T>,node<T>. |
模板是C++提供进行编程的一种类书工具。所以在看本文以前请先了解一下C++类书的概念及相关的知识。 1.模板的概念: 模办是实现类属机制的一种工具,它的功能非常强,它是无约束类属机制和约束类属机制的集合。它可以让用户构造模板函数。 模板,对象, 函数之间的关系见下图:
2.函数模板与模板函数: 先见下例: #include <iostream.h> template<class T> //模板声明 T max(T x,T y) //定义模板 main() 上面的这个程序虽然只是实现一个很简单的比较大小的问题, 但如果不用模板, 而用我们以前的方法,由于参数类型和返回值类型不同将需要三个函数来实现, 这样是十分麻烦的。模板成功的解决了这个问题, 程序中生成了三个模板函数,其中max(i,j)用模板实参int将类型实参数T进行了实例化;max(x1,x1)用模板实参float将类型参数T进行了实例化;max(y1,y2)用模板实参double将类型参数T进行了实例化。 从上面的例子我们可以看出, 函数模板提供了一类函数的抽象, 它以任意类型T为参数及函数返回值。由一个函数模板产生的函数称为模板函数,它是函数模板的具体实例。 函数模板和模板函数的关系图:
要提醒大家注意的一点是:虽然模板参数T可以实例化成各种类型, 但是采用模板参数T的各种参数T的各参数之间必须保持完全一致的类型。例如: T max(T x,T y) void func(int i, char c, float) 解决上面的问题就需要引入一个型的概念—重载, 既可以用非模板函数重载一个同名的函数模板。 重载有两种表述方式: 1.利用函数模板的函数体 使用次方法是必须注意各模板参数的实参类型必须一致。例如: int max(int,int) 2.重新定义函数体 对于要重新定义函数体的重载函数, 所带参数的类型可以随意, 就象一般的重载函数一样定义。 定义重载函数特别要注意避免产生预期的和非预期的二义性。例如: int max(int, int); char max(int x,char y)
(1)寻找一个参数完全匹配的函数,如果找到了就调用它。 (2)在(1)失败后, 寻找一个函数模板,使其实例化, 产生一个匹配的模板函数, 若找到了,就调用它。 (3)在(1)(2)均失败后,再试一试低一级的对函数的重载方法,例如通过类型转换可产生参数匹配等, 若找到了,就调用它。 (4)若(1)(2)(3)均失败,则这是一个错误的调用。 3.类模板与模板类 类模板与模板类的概念 一个类模板可以让用户为类定义一种模式, 使得类中的某些数据成员,某些成员函数的参数,某些成员函数的返回值,能取任意类型。 定义一个类模板,一般由两方面的内容: (1)首先要定义类,其格式为: template<class T> //声明一个模板 class name name为类名,在类定义体中如采用数据类型的成员, 函数参数的前面需加上T。例如: template<class T> class vector (2)在类定义体外定义成员函数时,若此成员函数中有模板参数存在, 则需在函数体外进行模板声明, 并且在函数名前的类名后缀上“<T>”.例如: template<class T> vector<T>::vector(int i) template<class T> T&vector<T>::operator[](int i) 类模板的使用 类模板的使用实际上是将类模板实例化成一个具体的类, 它的格式为: 类名<实际的类型> main() 类模板和模板类之间的关系, 如图:
类模板使用需要注意的几点: (1)在每个模板定义之前,不管是类模板还是函数模板, 都需要在前面加上模板声明: template<class T> (2)类模板和结构模板在使用时, 必须在名字后面缀上模板参数<T>,如:list<T>,node<T>.
|