程序设计基础:09第九章 类属机制_第1页
程序设计基础:09第九章 类属机制_第2页
程序设计基础:09第九章 类属机制_第3页
程序设计基础:09第九章 类属机制_第4页
程序设计基础:09第九章 类属机制_第5页
已阅读5页,还剩50页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第九章 类属机制,类属的作用 类属类的定义与实例化 类属类的继承关系 类属函数的定义与实例化,9.1 类属的基本概念,9.1.1 类型的严格性与灵活性 强类型语言:参与运算的所有对象的类型在编译时即可确定下来,编译程序进行严格类型检查。 好处: 避免类型不兼容错误 程序可靠性高 问题: 灵活性, 容器类(container)数据结构 :链表、堆栈、队列、集合、 需要放不同类型的对象。 多态数据结构:存放的元素类型必须从共同的基类派生出来。,9.1 类属的基本概念,9.1.2 解决冲突的途径 源代码复制: 函数重载 int max(int i, int j) float max(float i,

2、 float j) return ij?i:j; return ij?i:j; 宏定义(marco) #define max(a, b) (ab)?a:b) float x, y, z; int m, n, k; char c1, c2, c3; z=max(x, y); k=max(m, n); c3=max(c1, c2);,char str110, str220, str310; str3=max(str1, str2);,9.1 类属的基本概念,9.1.2 解决冲突的途径 运行时进行类型匹配检查 void *p; int m; float n; char c; p=,p+,下一个int

3、? 下一个float? 下一个,9.1 类属的基本概念,9.1.2 解决冲突的途径 数据类型作为类的参数 类属(genericity) C+采用模板(template)机制实现类属。 编程时只提供一套实现该功能的程序实体,然后将数据类作为参数传递,这就是类属机制的思想 既提高了数据类型的灵活性,又支持编译时做严格类型检查。,9.1 类属的基本概念,9.1.3 类属机制 类属是实现编译时多态性的另一种机制,这种机制通过将数据类型参数化使得程序具有多态性 由C+语言模板定义的类称为类属类(generic class)或参数化类(parameterized class)。 模板具有类属类属参数:将数

4、据类型作为模板的参数,参数化的数据类型就是类属类属参数 模板须经过实例化后才能使用:实例化是指用某一具体数据类型替代模板中的类属类属参数的过程,该确定的数据类型称为实际类属参数。 无约束类属类:实际类属参数可以是任何类型。 有约束类属类:实际类属参数具有某些特殊性质,如为PERSON类的派生类。 C+中用模板实现的类属类都是无约束类属类。受约束的类属类必须采用继承与动态绑定实现。,9.1.3 类属机制 C+语言的模板 函数模板(类属函数) 函数的形式参数表中某些形式参数的数据类型被参数化 函数模板本身不是函数,经实例化后才得到函数 类模板(类属类) 类的数据成员的类型或成员函数的形参类型被参数

5、化 类属类也不是类,经实例化后才得到具体的类,9.1 类属的基本概念,9.2 类模板,9.2.1 类属类的定义 一般形式: template class 类名 ; 形式类属参数表:用尖括号括起来的部分。用逗号隔开不同的形式类属参数,每个类属参数都由class引入 类属参数在类的声明中有效,在类外无效 在类的定义中,把这些类属参数当数据类型来声明各种变量,9.2.1 类属类的定义 例1. 用类模板对数组进行排序、检索和求和 #include template /声明一个形式类属参数T class ARRAY T*set;/ 定义数组元素集合 intn;/ 定义数组元素个数 public:ARRA

6、Y( T *data, int i) set= data ; n= i; ARRAY() void sort();/ 排序 int seek(T key); / 检索 T sum();/ 求和 ;,9.2 类模板,9.2.1 类属类的定义 template / 注意在类外声明类模板的 void ARRAY:sort()/ 成员函数的形式 int i, j;T d; for (i=1; i=i; j-) if (setj-1 setj) /交换setj-1和setj的值 d= setj-1; setj-1= setj; setj= d ; ,9.2 类模板,9.2.1 类属类的定义 templa

7、te int ARRAY:seek(T key) for (int i=0; i T ARRAY:sum() T s=0; for (int i=0; in; i+) s+= seti; return s; ,9.2 类模板,9.2.1 类属类的定义 例2. 类属链表类 /程序:GLIST.HPP /功能:定义链表类属类LIST的界面 template class LIST public: LIST(int length) vector=new ELEMENT_TYPElength; size=length; return; LIST() delete vector; return; ,9.2

8、 类模板,9.2.1 类属类的定义 /检索链表中的元素,利用重载运算符实现,函数返回值可作为左值 ELEMENT_TYPE ,9.2 类模板,9.2.1 类属类的定义 例3. 类属堆栈类 /程序:GSTACK.HPP /功能:定义堆栈类属类STACK的类界面和类的实现 #include #include #ifndef _GSTACK_HPP #define _GSTACK_HPP template class STACK public: STACK(); void push(ELEMENT_TYPE obj); void pop(); ELEMENT_TYPE get_top(); int

9、is_empty();,9.2 类模板,9.2.1 类属类的定义 private: struct NODE ELEMENT_TYPE element; NODE *link; ; NODE *top; ; template STACK:STACK() / 构造函数 top=NULL; / 将栈顶置为空 return; ,9.2 类模板,9.2.1 类属类的定义 template void STACK:push(ELEMENT_TYPE obj) /将obj压入栈顶 NODE *temp; temp=new NODE; if(temp!=NULL) temp-link=top; temp-ele

10、ment=obj; top=temp; else coutError: NO enough memory. n; exit(1); return; ,9.2 类模板,element,link,temp,top,obj2,link,obj1,link,obj,9.2.1 类属类的定义 template void STACK:pop() /将栈顶元素弹出 NODE *temp; if(top!=NULL) temp=top; top=top-link; delete temp; else coutError: Pop from empty stack. n; exit(1); return; ,9

11、.2 类模板,top,obj2,link,obj1,link,obj3,link,temp,9.2.1 类属类的定义 template ELEMENT_TYPE STACK:get_top() / 返回栈顶元素值 if(top=NULL) coutelement; template int STACK:is_empty() return (top=NULL); #endif,9.2 类模板,9.2.2 类属类的实例化 类模板不是类,不能用于创建对象,只有经过实例化后才得到类。 实例化的一般形式:类属类名字 例:STACK类模板,不能用于创建对象STACKint_stack;实例化: 用实际类属

12、参数int替换形式类属参数ELEMENT_TYPE后,得到一个整形堆栈类,即可用于声明对象。 一个类模板可以实例化为多个不同的类: STACK float_stack; STACK fig_stack;,9.2 类模板,9.2.2 类属类的实例化,9.2 类模板,类属类,整型类A,整型类B,整型类C,int,类A的对象,类B的对象,类C的对象,float,char,类属类实例化,类实例化,9.2.2 类属类的实例化 例1中声明的ARRAY类模板的实例化 void main() int i; int IData10 = 4, 2, 5, 3, 10, -4, -5, -2, 0, -3; ARR

13、AY myArray(IData, 10); cout IData myArray.seek(-5)=-5n; coutSum of IData is : myArray.sum() n; myArray.sort(); for (i=0; i10; i+) coutIDatai ; ,输出结果: IData6 = -5 Sum of IData is : 10 -5 -4 -3 -2 0 2 3 4 5 10,9.2 类模板,9.2.2 类属类的实例化 ARRAY myArray(IData, 10); #include template /声明一个形式类属参数T class ARRAY T

14、*set;/ 定义数组元素集合 intn;/ 定义数组元素个数 public:ARRAY( T *data, int i) set= data ; n= i; ARRAY() void sort();/ 排序 int seek( T key);/ 检索 T sum();/ 求和 ;,9.2 类模板,int,int,int,int,9.2.2 类属类的实例化 /程序:GSTACKDEMO.CPP /功能:演示类属堆栈类STACK的应用 #include gstack.hpp int main() STACKint_stack; STACKstr_stack; int_stack.push(5);

15、 int_stack.push(18); int_stack.push(24); if(!int_stack.is_empty() cout Top of integer stack is: int_stack.get_top()endl; int_stack.pop(); ,9.2 类模板,element,link,temp,5,int_stack.top,NULL,9.2.2 类属类的实例化 str_stack.push(合肥工业大学); str_stack.push(计算机与信息学院); if(!str_stack.is_empty() cout Top of string stack

16、is: str_stack.get_top()endl; str_stack.pop(); if(!int_stack.is_empty() cout Top of integer stack is: int_stack.get_top()endl; int_stack.pop(); int_stack.push(“ Push a string to integer stack. ”); /error str_stack.push(999); /error return 0; ,9.2 类模板,9.2.3 多个形式类属参数 类属类的形式类属参数可以有多个。 / 程序:MULPARA.CPP /

17、 功能:演示多个形式类属参数的用法 #include template class MULTI_PARA public: MULTI_PARA(TYPE1 x, TYPE2 y) first=x; second=y; return; void show() coutfirst secondendl; return; private: TYPE1 first; TYPE2 second; ;,9.2 类模板,9.2.3 多个形式类属参数 int main() MULTI_PARA obj1(2,3.14); MULTI_PARA obj2(Are you sure?, Y); obj1.show

18、(); obj2.show(); return 0; ,9.2 类模板,9.2.4 类属类的继承关系 一个类属类可以作为一个普通类的派生类 一个类属类也可作为其它类属类的基类 class BASE / 普通类作为基类 public: void get_value() coutvalue1 value2endl; return; protected: int value1; private: int valu2; ;,9.2 类模板,9.2.4 类属类的继承关系 template class DERIVED: public BASE / 类属类作为普通类的派生类 public: void set

19、_value(TYPE obj) value1=50; value2=100 / error,访问基类的私有成员 private: TYPE element; ;,9.2 类模板,9.2.4 类属类的继承关系 程序9.2.5 #include / 声明一个类属类作为基类。 template class BASE public: void show(TYPE obj) cout obj n; return; ;,9.2 类模板,9.2.4 类属类的继承关系 / 声明一个类属类作为BASE的派生类。 template class DERIVED: public BASE public:void s

20、how2(TYPE1 obj1, TYPE2 obj2) cout obj; /基类被实例化为BASE obj.show(3.14);/ 正确 obj.show2(Pi is: , 3.14159);/ 正确 / obj.show(“Has any error?”);/ 类型错误 / 形参类型是double,实参类型是字符串 return 0; ,9.2 类模板,9.2.4 类属类的继承关系 程序9.2.6 /程序:TEMPLAT2.CPP /功能:演示类属类作为基类,派生出类属类的用法 #include template struct Node T val; Node *next; ;,9.

21、2 类模板,9.2.4 类属类的继承关系 template class List / 类属类作为基类 protected: Node *head; int size; public: List() head=NULL; size=0; virtual bool insert(T val); bool deletes(T val); bool contains(T val); void print(); List(); ;,9.2 类模板,9.2.4 类属类的继承关系 template List:List() Node *temp; for(Node *p=head; p; ) temp=p;

22、p=p-next; delete temp; ,9.2 类模板,9.2.4 类属类的继承关系 template bool List:insert(T x) Node *nodes=new Node; if(nodes) nodes-val=x; nodes-next=head; head=nodes; size+; return true; return false; ,9.2 类模板,9.2.4 类属类的继承关系 template bool List:deletes(T x) Node *temp; if(head-val=x) temp=head-next; delete head;siz

23、e-; head=temp; return ture; for(Node *p=temp=head; temp=p; p=p-next) if(p-val=x) ,9.2 类模板,9.2.4 类属类的继承关系 template bool List:contains(T x) for(Node *p=head; p; p=p-next) if(p-val=x) return true; return false; template void List:print() for(Node *p=head; p; p=p-next) coutval ; coutendl; ,9.2 类模板,9.2.4

24、 类属类的继承关系 template class Set:public List / 派生类也是类属类 public: bool insert(T val); ; template bool Set:insert(T val) if(!(List:contains(val) ,9.2 类模板,9.2.4 类属类的继承关系 void main() cout intlist; intlist.insert(33); intlist.insert(85); intlist.insert(78); intlist.insert(46); intlist.insert(85); intlist.prin

25、t(); List doublelist; doublelist.insert(34.56); doublelist.insert(66.4); doublelist.insert(8549.67); doublelist.insert(498.56); doublelist.insert(66.4); doublelist.print(); List charlist; charlist.insert(Computer.); charlist.insert(Windows.); charlist.insert(Constructor.); charlist.insert(virtual_fu

26、ction.); charlist.print(); Set intset; intset.insert(33); intset.insert(85); intset.insert(78); intset.insert(46); intset.insert(85); intset.print(); ,9.2 类模板,9.2.4 类属类的继承关系 程序9.2.7 class Set:public List / 继承时给出实际类型参数 public: bool insert(int val); ; bool Set:insert(int val) if(!(List:contains(val) ,

27、9.2 类模板,9.2.4 类属类的继承关系 void main() cout intlist; intlist.insert(33); intlist.insert(85); intlist.insert(78); intlist.insert(46); intlist.insert(85); intlist.print(); List doublelist; doublelist.insert(34.56); doublelist.insert(66.4); doublelist.insert(8549.67); doublelist.insert(498.56); doublelist.

28、insert(66.4); doublelist.print(); List charlist; charlist.insert(Computer.); charlist.insert(Windows.); charlist.insert(Constructor.); charlist.insert(virtual_fuction.); charlist.print(); Set intset; intset.insert(33); intset.insert(85); intset.insert(78); intset.insert(46); intset.insert(85); intse

29、t.print(); ,9.2 类模板,9.2.4 类属类的继承关系 程序9.2.8 /程序:TEMPLAT4.CPP /功能:演示非类属类作为基类,派生出类属类的用法 #include class Base / 普通类为基类 protected: int val1, val2; public: Base(int x=0, int y=0) val1=x; val2=y; int addint() return(val1+val2); int subint() return(val1-val2); void print() coutnOUTPUT(Base) val1: val1tval2:

30、val2t; cout(val1+val2)=addint()t(val1-val2)=subint()endl; ;,9.2 类模板,9.2.4 类属类的继承关系 template class Derived: public Base / 派生类为类属类 protected: TYPE val3; public: Derived(int i, int j, TYPE k): Base(i,j) val3=k; TYPE div() return(val1/val3); TYPE mul() return(val2*val3); void print() Base:print(); coutn

31、OUTPUT(Derived) val1: val1tval2: val2t; coutval3: val3t; cout(val1/val3)=div()t(val1*val3)=mul()endl; ;,9.2 类模板,9.2.4 类属类的继承关系 void main() cout d1(15,20,325); d1.print(); cout d2(15,20,32500.98); d2.print(); cout d3(15,20,3250000.98); d3.print(); ,9.2 类模板,9.3 函数模板,9.3.1 类属函数 一般形式: template 函数类型 函数名(

32、形参表) 函数体 例:template TYPE max(TYPE x, TYPE y) return (x y) ? x : y; ,9.3 函数模板,9.3.1 类属函数 当应用程序使用类属函数时,编译程序将根据函数调用时的实际数据类型产生相应的函数: int i, j, k; double a, b, c; MY_CLASS obj, obj1, obj2; k=max(i, j); c=mac(a, b); obj=max(obj1,obj2);,int max(int x, int y) return (x y) ? x : y;,double max(double x, doubl

33、e y) return (x y) ? x : y;,MY_CLASS max(MY_CLASS x, MY_CLASS y) return (x y) ? x : y;,9.3.1 类属函数 函数模板定义时应注意的问题 在函数模板定义template中给出的每一个形式类属参数都必须出现在函数形参表中 如: template void fun(T1 x, T2 y) 错误的用法 template template TYPE* func( ) void func( ) TYPE obj; 对于类模板的成员函数则不做此项要求,9.3 函数模板,9.3.3 函数模板的实例化 由编译系统根据函数调用的

34、实际参数类型自动完成函数模板的实例化,不须显式实例化 template TYPE max(TYPE x, TYPE y) return (x y) ? x : y; void main( ) MY_CLASS obj1, obj2; max(10, 5);/ 用整型实例化 max(obj1, obj2); / 用MY_CLASS实例化 ,9.3 函数模板,9.3.3 函数模板的实例化 调用类属函数时,应保证函数的实参类型与形式类属参数完全匹配因为函数模板在实例化过程中不做任何类型转换 例:已知函数模板max的两个形参都是形式类属参数TYPE类型的,则以下两个应用错误 max(10, 10.5);一个实参是整型,另一个是double型,类型不同 max(10, obj1);一个实参是整型,另一个是MY_CLASS类型 都无法实例化,9.3 函数模板,9.3.3 函数模板的实例化 函数调用匹配次序: (1)如果某一函数的参数类型正好与函数调用的实际参数类型匹配,则调用该函数。否则 (2)如果能从同名

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论