第19章 类模板
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十九章 类模板
杨章伟 e-mail:yang505412@
课程内容安排
• • • • • •
了解类模板的概念,以及为什么使用类模板; 掌握类模板的定义; 了解类模板和模板类的区别; 掌握类模板的实例化; 熟悉类模板的特化和偏特化; 熟悉类模板的匹配规则。
1-2
类模板
• 顾名思义,类模板就是类的模板。同函数模板一样,类 的模板也是对数据的类型进行了参数化处理。将类模板 实例化,也就是指定数据的具体类型,将得到一个具体 的、可以用来定义对象的类。类模板同函数模板一样, 所能接受的具体类型参数都是有限制的。具体哪些类型 可以用来实例化模板,要看模板的具体定义。 类模板是C++语言的一个非常重要的特征,也代表着某 种 编 程 趋 势 —— 泛 型 编 程 。 在 C++ 的 标 准 模 板 库 ( Standard Template Library,简称STL)中就提供了 大量的类模板,如list、deque、 map、set、vector 、stack、queue等。
1-15
【分析】该试题主要考察在类模板中声明的函数在类外进行 实现的问题。根据前面的学习,读者知道在类模板中声 明的函数如果在类外进行具体定义,需要加上模板名 template <class T>和作用域运算符,表示该成员函数 的归属。==运算符的重载即实现比较类中似有成员n的值 是否相等,通过简单的分支语句即可实现。 【核心代码】 template <class T> int Sample<T>::operator==(Sample &s) { if(n==s.n) return 1; else return 0; }
1-19
• • • •
1-7
类模板的特化
有的时候某些类型不能直接用来实例化类模板,或者 说直接实例化不能满足需要,此时就要针对这种类型 进行的特化,包括完全特化和偏特化。
类模板的特化是为了针对特殊的类型,进行特殊的处 理。
1-8
小结
本章主要讲述了类模板的概念及类模板的定义和实例化。C++中 的类模板与普通类相似,可以定义自己的函数成员、静态成员 、友元函数等。类模板有特化和今偏特化两种,要注意在此之 前需要普通类模板的定义。
1-16
【题目276】设计一个模板类Sample,用于对一个有序数 组采用二分法查找元素下标。 【分析】该试题主要考查类模板的设计和实现问题。该试题 要求设计一个模板类,其中必然要包含数组的声明,其 作为模板类的似有成员;而采用二分法查找数组下标的 实现函数作为模板类的成员函数在类中进行声明,类外 进行具体实现。因此,模板类Sample的设计如下。
1-12
【题目273】分析以下程序的执行结果 #include<iostream> template<class T> class Sample { T n; public: Sample(){} Sample(T i){n=i;} Sample<T>&operator+(consta Sample<T>&); void disp(){cout<<"n="<<n<<endl;} }; template<class T> Sample<T>&Sample<T>::operator+(const Sample<T>&s) { static Sample<T> temp; temp.n=n+s.n; return temp; } int main() { Sample<int>s1(10),s2(20),s3; s3=s1+s2; s3.disp(); }
实例化类模板时,对于类型参数,可以用C++内建的类型实 例化,也可以用自定义的类型。与函数模板不同的是,类模 板在实例化时没有参数推导机制,所有的模板参数必须指定 ,除非模板参数带有缺省实参。
•
1-5
类模板的静态成员
• 与普通类一样,模板也可以有自己的静态成员。所不同 的是,每种类型的类模板的实例有自己的一组静态成员 。与普通类的静态成员初始化一样,类模板的静态成员 也需要类内声明,在类外定义。其在类外定义的格式如 下: template <类型名 参数名1,类型名 参数名2,…> 类型名 类名<类型名 参数名1,类型名 参数名2,…>:: 静态数据成员= 初始化值;
1-13
【分析】该试题主要考查类模板的使用方法和重载运算符的 实现。在上述程序段中,Sample为一个类模板,产生一 个模板类Sample<int>,并建立它的三个对象,调用重 载运算符+实现s1与s2的加法运算,将结果赋给s3。读者 可以看出,重载后的运算符+能够实现两个对象直接的加 法运算,因此,该程序段的输出为s=30。 【题目274】设计一个数组类模板Array<T>,其中包含重载 下标运算符函数,并由此产生模板类Array<int>和 Array<char>,使用一些测试数据对其进行测试。 【分析】该试题主要考查类模板的实现以及在主函数中的实 例化。此处首先设计一个数组类模板,该模板中包含下 标运算符的重载函数,读者可以选择在类外实现该函数 的定义。在主函数中定义整型数组和字符型数组并初始 化,将类模板分别实例化为整型和字符型,查看输出结 果。
1-14
【题目275】已知一个Sample类模板的私有数据成员为T n ,在该类模板中设计一个operator==重载运算符函数 , 用于比较各对象的n数据是否相等。 template <class T> class Sample { T n; public: Sample(T i){n=i;} int operator==(Sample &); };
template <typename 参数名1,typename 参数名2,…> class 类模板名 { // 类体 };
• • • • •
•
需要读者注意的是,类模板定义最后的分号不可省,因 为与类的定义一样,类模板的定义也是一条语句,需要 一个分号作为语句的结束。
1-4
生成类模板
• 类模板只是一个模板,不是实际的类。使用类模板时,必须 先实例化,即给类模板参数赋值,包括类型参数和非类型参 数。本节将详细讨论如何实例化类模板。有的文献将类模板 实例化的结果称作模板类,读者在阅读的时候注意区分这两 个概念。类模板是模板,而模板类则是模板实例化的结果— —是真正可以用来声明对象的类。•Fra bibliotek1-3
定义类模板
• 一个类模板的定义以关键字template作为开始,后面 跟一对尖括号,尖括号的里面是模板参数列表。模板参 数之间用逗号分隔。如果是类型参数,则以typename 或class声明;如果是非类型参数,则其声明语法同普 通函数参数的声明语法类似。在模板参数列表之后,可 以像定义类一样来定义类模板。语法如下所示:
1-9
习题
【题目271】分析以下程序的执行结果。 #include<iostream> template <class T> class Sample { T n; public: Sample(T i){n=i;} void operator++(); void disp(){cout<<"n="<<n<<endl;} }; template <class T> void Sample<T>::operator++() { n+=1; // 不能用n++;因为double型不能用++ } int main() { Sample<char> s('a'); s++; s.disp(); }
1-17
【题目277】设计、实现并测试一个对具有size个元素的数 组求最大值的应用,要求用函数模版完成。 【分析】该试题主要考察函数模板的应用。该程序设计一个 函数模板,参数为具有size个元素的数组,在函数体中通 过循环比较数组中的每个元素,将其最大的赋值给变了 max,并返回max的值,即完成了题目的要求。
1-10
【分析】该试题主要考查类模板的使用方法。在上述程序段 中 , Sample 是 一 个 类 模 板 , 由 它 产 生 模 板 类 Sample<char>,通过构造函数给n赋初值,通过重载++ 运算符使n增1,这里n由'a'增1变成'b'。因此,该试题的 输出结果为n=b。
1-11
【题目272】编写一个使用类模板对数组进行排序、查找和求元素 和的程序。 【分析】该试题主要考查类模板的实现问题。在对数组的操作中, 排序、查找和求元素和都是使用非常频繁的操作,为了对各种数 据类型的数组都能进行上述几种操作,有必要编写一个类模板来 实现。改试题可以设计一个类模板template<class T>class Array,用于对T类型的数组进行排序、查找和求元素和,然后由 此产生模板类Array<int>和Array<double>。
【题目278】设计、实现并测试一个类模版,对数组元素进 行排序。 【分析】该试题主要考查类模板的设计。该程序设计一个类 模板,包括数组名和长度等2个私有成员,包括构造函数 、析构函数和排序函数等3个公有成员,在类外定义排序 函数的函数体,采用冒泡排序法进行排序。
1-18
【题目279】设计、实现并测试一个类模版,在数组中查找 指定元素x,查找成功则返回值1,否则返回值0 【分析】该试题主要考查类模板的设计。该程序设计一个类 模板,包括数组名和长度等2个私有成员,包括构造函数 、析构函数和排序函数等3个公有成员,在类外定义排序 函数的函数体,通过循环依次比较数组中的每个元素与x 的值是否相等,是则返回值1,否则返回值0。 【题目280】设计一个Sample类,其数据和方法均包含在 该类中,而且使用类模板的方式实现插入排序、冒泡排 序、快速排序等。
• •
1-6
类模板的友元
• 类模板的友元和普通类的友元一样,使其友元类或者友 元函数拥有存取的特权,即可以访问到类中的私有或保 护的数据成员和成员函数。有三种友元可以出现在类模 板中: 非模板的友元类和友元函数; 与模板参数不绑定的友元类和友元函数模板; 与模板参数绑定的友元类和友元函数模板。 1.非模板的友元类和友元函数
杨章伟 e-mail:yang505412@
课程内容安排
• • • • • •
了解类模板的概念,以及为什么使用类模板; 掌握类模板的定义; 了解类模板和模板类的区别; 掌握类模板的实例化; 熟悉类模板的特化和偏特化; 熟悉类模板的匹配规则。
1-2
类模板
• 顾名思义,类模板就是类的模板。同函数模板一样,类 的模板也是对数据的类型进行了参数化处理。将类模板 实例化,也就是指定数据的具体类型,将得到一个具体 的、可以用来定义对象的类。类模板同函数模板一样, 所能接受的具体类型参数都是有限制的。具体哪些类型 可以用来实例化模板,要看模板的具体定义。 类模板是C++语言的一个非常重要的特征,也代表着某 种 编 程 趋 势 —— 泛 型 编 程 。 在 C++ 的 标 准 模 板 库 ( Standard Template Library,简称STL)中就提供了 大量的类模板,如list、deque、 map、set、vector 、stack、queue等。
1-15
【分析】该试题主要考察在类模板中声明的函数在类外进行 实现的问题。根据前面的学习,读者知道在类模板中声 明的函数如果在类外进行具体定义,需要加上模板名 template <class T>和作用域运算符,表示该成员函数 的归属。==运算符的重载即实现比较类中似有成员n的值 是否相等,通过简单的分支语句即可实现。 【核心代码】 template <class T> int Sample<T>::operator==(Sample &s) { if(n==s.n) return 1; else return 0; }
1-19
• • • •
1-7
类模板的特化
有的时候某些类型不能直接用来实例化类模板,或者 说直接实例化不能满足需要,此时就要针对这种类型 进行的特化,包括完全特化和偏特化。
类模板的特化是为了针对特殊的类型,进行特殊的处 理。
1-8
小结
本章主要讲述了类模板的概念及类模板的定义和实例化。C++中 的类模板与普通类相似,可以定义自己的函数成员、静态成员 、友元函数等。类模板有特化和今偏特化两种,要注意在此之 前需要普通类模板的定义。
1-16
【题目276】设计一个模板类Sample,用于对一个有序数 组采用二分法查找元素下标。 【分析】该试题主要考查类模板的设计和实现问题。该试题 要求设计一个模板类,其中必然要包含数组的声明,其 作为模板类的似有成员;而采用二分法查找数组下标的 实现函数作为模板类的成员函数在类中进行声明,类外 进行具体实现。因此,模板类Sample的设计如下。
1-12
【题目273】分析以下程序的执行结果 #include<iostream> template<class T> class Sample { T n; public: Sample(){} Sample(T i){n=i;} Sample<T>&operator+(consta Sample<T>&); void disp(){cout<<"n="<<n<<endl;} }; template<class T> Sample<T>&Sample<T>::operator+(const Sample<T>&s) { static Sample<T> temp; temp.n=n+s.n; return temp; } int main() { Sample<int>s1(10),s2(20),s3; s3=s1+s2; s3.disp(); }
实例化类模板时,对于类型参数,可以用C++内建的类型实 例化,也可以用自定义的类型。与函数模板不同的是,类模 板在实例化时没有参数推导机制,所有的模板参数必须指定 ,除非模板参数带有缺省实参。
•
1-5
类模板的静态成员
• 与普通类一样,模板也可以有自己的静态成员。所不同 的是,每种类型的类模板的实例有自己的一组静态成员 。与普通类的静态成员初始化一样,类模板的静态成员 也需要类内声明,在类外定义。其在类外定义的格式如 下: template <类型名 参数名1,类型名 参数名2,…> 类型名 类名<类型名 参数名1,类型名 参数名2,…>:: 静态数据成员= 初始化值;
1-13
【分析】该试题主要考查类模板的使用方法和重载运算符的 实现。在上述程序段中,Sample为一个类模板,产生一 个模板类Sample<int>,并建立它的三个对象,调用重 载运算符+实现s1与s2的加法运算,将结果赋给s3。读者 可以看出,重载后的运算符+能够实现两个对象直接的加 法运算,因此,该程序段的输出为s=30。 【题目274】设计一个数组类模板Array<T>,其中包含重载 下标运算符函数,并由此产生模板类Array<int>和 Array<char>,使用一些测试数据对其进行测试。 【分析】该试题主要考查类模板的实现以及在主函数中的实 例化。此处首先设计一个数组类模板,该模板中包含下 标运算符的重载函数,读者可以选择在类外实现该函数 的定义。在主函数中定义整型数组和字符型数组并初始 化,将类模板分别实例化为整型和字符型,查看输出结 果。
1-14
【题目275】已知一个Sample类模板的私有数据成员为T n ,在该类模板中设计一个operator==重载运算符函数 , 用于比较各对象的n数据是否相等。 template <class T> class Sample { T n; public: Sample(T i){n=i;} int operator==(Sample &); };
template <typename 参数名1,typename 参数名2,…> class 类模板名 { // 类体 };
• • • • •
•
需要读者注意的是,类模板定义最后的分号不可省,因 为与类的定义一样,类模板的定义也是一条语句,需要 一个分号作为语句的结束。
1-4
生成类模板
• 类模板只是一个模板,不是实际的类。使用类模板时,必须 先实例化,即给类模板参数赋值,包括类型参数和非类型参 数。本节将详细讨论如何实例化类模板。有的文献将类模板 实例化的结果称作模板类,读者在阅读的时候注意区分这两 个概念。类模板是模板,而模板类则是模板实例化的结果— —是真正可以用来声明对象的类。•Fra bibliotek1-3
定义类模板
• 一个类模板的定义以关键字template作为开始,后面 跟一对尖括号,尖括号的里面是模板参数列表。模板参 数之间用逗号分隔。如果是类型参数,则以typename 或class声明;如果是非类型参数,则其声明语法同普 通函数参数的声明语法类似。在模板参数列表之后,可 以像定义类一样来定义类模板。语法如下所示:
1-9
习题
【题目271】分析以下程序的执行结果。 #include<iostream> template <class T> class Sample { T n; public: Sample(T i){n=i;} void operator++(); void disp(){cout<<"n="<<n<<endl;} }; template <class T> void Sample<T>::operator++() { n+=1; // 不能用n++;因为double型不能用++ } int main() { Sample<char> s('a'); s++; s.disp(); }
1-17
【题目277】设计、实现并测试一个对具有size个元素的数 组求最大值的应用,要求用函数模版完成。 【分析】该试题主要考察函数模板的应用。该程序设计一个 函数模板,参数为具有size个元素的数组,在函数体中通 过循环比较数组中的每个元素,将其最大的赋值给变了 max,并返回max的值,即完成了题目的要求。
1-10
【分析】该试题主要考查类模板的使用方法。在上述程序段 中 , Sample 是 一 个 类 模 板 , 由 它 产 生 模 板 类 Sample<char>,通过构造函数给n赋初值,通过重载++ 运算符使n增1,这里n由'a'增1变成'b'。因此,该试题的 输出结果为n=b。
1-11
【题目272】编写一个使用类模板对数组进行排序、查找和求元素 和的程序。 【分析】该试题主要考查类模板的实现问题。在对数组的操作中, 排序、查找和求元素和都是使用非常频繁的操作,为了对各种数 据类型的数组都能进行上述几种操作,有必要编写一个类模板来 实现。改试题可以设计一个类模板template<class T>class Array,用于对T类型的数组进行排序、查找和求元素和,然后由 此产生模板类Array<int>和Array<double>。
【题目278】设计、实现并测试一个类模版,对数组元素进 行排序。 【分析】该试题主要考查类模板的设计。该程序设计一个类 模板,包括数组名和长度等2个私有成员,包括构造函数 、析构函数和排序函数等3个公有成员,在类外定义排序 函数的函数体,采用冒泡排序法进行排序。
1-18
【题目279】设计、实现并测试一个类模版,在数组中查找 指定元素x,查找成功则返回值1,否则返回值0 【分析】该试题主要考查类模板的设计。该程序设计一个类 模板,包括数组名和长度等2个私有成员,包括构造函数 、析构函数和排序函数等3个公有成员,在类外定义排序 函数的函数体,通过循环依次比较数组中的每个元素与x 的值是否相等,是则返回值1,否则返回值0。 【题目280】设计一个Sample类,其数据和方法均包含在 该类中,而且使用类模板的方式实现插入排序、冒泡排 序、快速排序等。
• •
1-6
类模板的友元
• 类模板的友元和普通类的友元一样,使其友元类或者友 元函数拥有存取的特权,即可以访问到类中的私有或保 护的数据成员和成员函数。有三种友元可以出现在类模 板中: 非模板的友元类和友元函数; 与模板参数不绑定的友元类和友元函数模板; 与模板参数绑定的友元类和友元函数模板。 1.非模板的友元类和友元函数