




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第九章
类属机制类属的作用类属类的定义与实例化类属类的继承关系类属函数的定义与实例化§9.1类属类属是实现编译时多态性的另一种机制,这种机制通过将数据类型参数化使得程序具有多态性类属机制的基本思想:实际应用中,一些函数的功能相同,唯一的区别只在于处理对象的数据类型不同,若用函数重载实现,则需编写多个函数:例:intmax(inti,intj) floatmax(floati,floatj) {returni>j?i:j;} {returni>j?i:j;}编程时只提供一套实现该功能的程序实体,然后将数据类型作为参数传递,这就是类属机制的思想C++语言中,使用模板来实现类属机制模板具有形式类属参数:将数据类型作为模板的参数,参数化的数据类型就是形式类属参数模板须经过实例化后才能使用:实例化是指用某一具体数据类型替代模板中的形式类属参数的过程,该确定的数据类型称为实际类属参数。C++语言的模板函数模板(类属函数)函数的形式参数表中某些形式参数的数据类型被参数化函数模板本身不是函数,经实例化后才得到函数类模板(类属类)类的数据成员的类型或成员函数的形参类型被参数化类属类也不是类,经实例化后才得到具体的类§9.2类模板
一、类属类的定义一般形式:template<class类属参数1,class类属参数2,…>class类名{
…};
形式类属参数表:用尖括号括起来的部分。用逗号隔开不同的形式类属参数,每个类属参数都由class引入类属参数在类的声明中有效,在类外无效在类的定义中,把这些类属参数当数据类型来声明各种变量例1:用类模板对数组进行排序、检索和求和#include<iostream.h>template<classT> // 声明一个形式类属参数TclassARRAY{ T *set; //定义数组元素集合
int n; //定义数组元素个数public: ARRAY(T*data,inti) { set =data; n =i; } ~ARRAY(){} voidsort(); //排序
intseek(Tkey); //检索
Tsum(); //求和};template<classT> //注意在类外声明类模板的voidARRAY<T>::sort() //成员函数的形式{
inti,j; Td; for(i=1;i<n;i++)//冒泡排序
for(j=n-1;j>=i;j--){ if(set[j-1]>set[j]){//交换set[j-1]和set[j]的值
d =set[j-1]; set[j-1] =set[j]; set[j] =d; } }}template<classT>intARRAY<T>::seek(Tkey){ for(inti=0;i<n;i++) if(set[i]==key)returni;//找到,则返回key在数组中的位置
return-1; //找不到,返回-1}template<classT>TARRAY<T>::sum(){ T s=0; for(inti=0;i<n;i++) s +=set[i]; returns;}例2:条件编译预处理命令
#ifdef标识符1 程序段1 #else
程序段2 #endif若标识符1已用define宏定义过,则程序段1参与编译,否则编译程序段2,在编译阶段实现分支结构例:#include<iostream.h>#defineMAXvoidmain(){ inta,b,t;
cout<<“Inputtwointeger:”;
cin>>a>>b;#ifdefMAX t=a>b?a:b; //如定义了MAX,则求最大值#else
t=a<b?a:b; //如没有定义了MAX,则求最小值#endif
cout<<t;}//条件编译预处理命令的另一种形式#ifndef标识符1 若标识符1未用define宏 程序段1 定义过,则程序段1参与#else
编译,否则编译程序段2
程序段2#endif两种形式的条件编译都可省略else分支例:#ifndefTEST_DEF 若TEST_DEF未定义,则中#defineTEST_DEF
间的这段程序参与编译,在classTEST_DEF{
该程序段中,首先宏定义……
TEST_DEF,当下次程序再次};
经过该处时,TEST_DEF已#endif 定义过,于是不再编译。保证该程序段在整个工程中只被唯一的编译一次二、类属类的实例化类模板不是类,不能用于创建对象,只有经过实例化后才得到类实例化的一般形式: 类属类名字<实际类属参数表>
例: STACK
类模板,不能用于创建对象 STACK<int> obj; 实例化:用实际类属参数int替换形式类属参数ELEMENT_TYPE后,得到一个整形堆栈类,即可用于声明对象。一个类模板可以实例化为多个不同的类例1中声明的ARRAY类模板的实例化voidmain(){ inti; intIData[10]={4,2,5,3,10,-4,-5,-2,0,-3};
ARRAY<int>
myArray(IData,10); cout<<"IData["<<myArray.seek(-5)<<"]=-5"<<"\n"; cout<<"SumofIDatais:"<<myArray.sum()<<"\n"; myArray.sort(); for(i=0;i<10;i++) cout<<IData[i]<<"";}输出结果:Idata[6]=-5SumofIDatais:10-5-4-3-20234510三、类属类的继承关系一个类模板可以作为一个普通类的派生类一个类模板也可作为其它类模板的基类例:#include<iostream.h>
//声明一个类属类作为基类。template<classTYPE>classBASE{public: voidshow(TYPEobj) {
cout<<obj<<"\n"; return; }};//声明一个类属类作为BASE的派生类。template<classTYPE1,classTYPE2>classDERIVED:
publicBASE<TYPE2>{public: voidshow2(TYPE1obj1,TYPE2obj2) {
cout<<obj1<<""<<obj2<<"\n"; return; }};
//演示类属类层次的用法intmain(){ DERIVED<char*,double>obj;//基类被实例化为BASE<double>
obj.show(3.14); //正确
obj.show2("Piis:",3.14159); //正确 //obj.show(“Hasanyerror?”); //类型错误 //
形参类型是double,实参类型是字符串
return0;}§9.3函数模板
一、类属函数一般形式:template<class类属参数1,class类属参数2,…>函数类型 函数名(形参表){ 函数体…}
例: template<classTYPE> TYPEmax(TYPEx,TYPEy) { return(x>y)?x:y; }
函数模板定义时应注意的问题在函数模板定义template中给出的每一个形式类属参数都必须出现在函数形参表中如: template<classT1,classT2> voidfun(T1x,T2y) {…… }
错误的用法template<classTYPE> template<classTYPE>TYPE*func()
voidfunc()
{……} {TYPEobj; …… }
对于类模板的成员函数则不做此项要求函数模板的实例化由编译系统根据函数调用的实际参数类型自动完成函数模板的实例化,不须显式实例化template<classTYPE>TYPEmax(TYPEx,TYPEy){ return(x>y)?x:y;}voidmain(){ MY_CLASS obj1,obj2; max(10,5); //用整型实例化
max(obj1,obj2); //用MY_CLASS实例化}调用类属函数时,应保证函数的实参类型与形式类属参数完全匹配因为函数模板在实例化过程中不做任何类型转换例:已知函数模板max的两个形参都是形式类属参数TYPE类型的,则以下两个应用错误max(10,10.5); 一个实参是整型,另一个是double型,类型不同max(10,obj1); 一个实参是整型,另一个是MY_CLASS类型都无法实例化二、类属函数的重载
例:#include<iostream.h>template<classTYPE>TYPEmax(TYPEx,TYPEy){ return(x>=y)?x:y;}template<classTYPE>TYPEmax(TYPEx,TYPEy,TYPEz){ TYPEw=(x>=y)?x:y; return(w>=z)?w:z;}template<classTYPE>TYPEmax(TYPEx[],intn){ TYPEm=x[0]; for(inti=0;i<n;i++) if(m<x[i]) m=x[i]; returnm;}voidmain(){ floatm,x=56,y=-55.8,z=99.1; intdata[10]={1,3,15,7,9,22,4,26,8,10}; m=max(x,y); //TYPE被实例化为float m=max(x,y,z);
intt=max(data,10);}在引入类属函数后,确定调用函数的哪个版本所遵循的匹配原则:(1)如果某一普通函数的形参类型正好与函数调用的实际参数类型匹配,则调用该函数。否则,(2)如果能从同名的类属函数实例化一个函数实例,而该函数的参数类型正好与函数调用的实际参数类型匹配,则调用该实例化的函数。否则,(3)对函数调用的实际参数作隐式类型转换后与非类属函数再作匹配,找到匹配的函数则调用它。否则,(4)提示语法错误。
例1:
#include<iostream.h>
template<classTYPE>voidswap(TYPE&x,TYPE&y)//声明一个函数模板swap{ TYPEtemp;
temp=x; x=y; y=temp; cout<<"Callinggenericversionofswap().\n";}
voidswap(int&x,int&y)//重载swap,定义一特殊版本(不是模板){ inttemp;
temp=x; x=y; y=temp; cout<<"Callingspecialversionofswap().\n";}
intmain(){ inti=10,j=20;floatx=1.44,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 脑出血稳定期的护理查房
- 手术室的麻醉护理
- 心理健康主题班会设计与实践
- 危重患者术中护理
- 幼儿心理健康的标准
- 呼吸内科危重患者的抢救
- 大学生全国教育大会
- 护理不良事件上报与管理流程
- 企业IT数字化转型大数据平台架构设计建设方案
- 2025年金融数据加密机项目提案报告
- 2025年广东省高考生物真题(解析版)
- 2025年7月自考13811绩效管理试题及答案含解析
- 2025年中学教师资格考试《综合素质》教育法律法规经典案例分析及强化试题集(含答案)
- CGF生长因子在口腔医学中的应用
- 互联网新闻信息服务安全评估报告模板(2025年7月修订)
- 《等腰三角形的性质》课件
- 工业互联网与船舶行业融合应用参考指南 2025
- 应征公民政治考核表(含示例)
- 南通国家级南通经济技术开发区公开招聘招商人员笔试历年参考题库附带答案详解析
- 2025年广东省深圳市中考道德与法治 总复习法治教育检测卷(含答案)
- 先天性甲状腺功能减退症诊治指南(2025)解读
评论
0/150
提交评论