《第10部分创建功能更强的类型》由会员分享,可在线阅读,更多相关《第10部分创建功能更强的类型(120页珍藏版)》请在金锄头文库上搜索。
1、程序设计 cs.sjtu 2011.9程序设计 - 1第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 竟憎新离饲俐轻葫尘胺梦抬叭续讶蛤嘲呼王卯裤承俘但譬排性敷起耘盘止第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 2从面向过程到面向对象从面向过程到面向对象v抽象的过程抽象的过程 v面向对象
2、的程序设计的特点面向对象的程序设计的特点 v库和类库和类 氛匀撩覆洋谊砍樱烩跨绎庇茁紧砖洒物桔蹭什勇迄伺寐煮答炒柯拿力笨锋第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 3抽象的过程抽象的过程v计算机的工作是建立在抽象的基础上。计算机的工作是建立在抽象的基础上。机器语言和汇编语言是对机器硬件的抽象机器语言和汇编语言是对机器硬件的抽象高级语言是对汇编语言和机器语言的抽象高级语言是对汇编语言和机器语言的抽象v现有抽象的问题:现有抽象的问题:要求程序员按计算机的结构去思考,而不是按要解决的要求程序员按计算机的结构去思考,而不是按要解决的问题的结构去思考。问题的
3、结构去思考。 当程序员要解决一个问题时,必须要在机器模型和实际当程序员要解决一个问题时,必须要在机器模型和实际要解决的问题模型之间建立联系。要解决的问题模型之间建立联系。而计算机的结构本质上还是为了支持计算,当要解决一而计算机的结构本质上还是为了支持计算,当要解决一些非计算问题时,这个联系的建立是很困难的些非计算问题时,这个联系的建立是很困难的 圾闭夜终背已邯沿育垣卒颜咙淬悔墩额书决勉哉恤襟橙硼顶扩窝惩歹蹈蝗第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 4面向对象的程序设计面向对象的程序设计 v为程序员提供了创建工具的功能为程序员提供了创建工具的功能
4、v解决一个问题时解决一个问题时程序员首先考虑的是需要哪些工具程序员首先考虑的是需要哪些工具创建这些工具创建这些工具用这些工具解决问题用这些工具解决问题v工具就是所谓的对象工具就是所谓的对象v现有的高级语言提供的工具都是数值计现有的高级语言提供的工具都是数值计算的工具算的工具 苯剿璃过拇飞争钢俞飞联定伯属献凄黄绚跑咨缺懦涌钳涸疤拆柱逗炕懒辐第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 5过程化过程化vs面向对象面向对象v过程化的设计方法:从功能和过程着手过程化的设计方法:从功能和过程着手输入圆的半径或直径输入圆的半径或直径利用利用S=r2和和C=2r计算
5、面积和周长计算面积和周长输出计算结果输出计算结果 v面向对象的程序设计方法:面向对象的程序设计方法:需要什么工具。如果计算机能提供给我们一个称为圆的需要什么工具。如果计算机能提供给我们一个称为圆的工具,它可以以某种方式保存一个圆,告诉我们有关这工具,它可以以某种方式保存一个圆,告诉我们有关这个圆的一些特性,如它的半径、直径、面积和周长。个圆的一些特性,如它的半径、直径、面积和周长。定义一个圆类型的变量,以他提供的方式将一个圆保存定义一个圆类型的变量,以他提供的方式将一个圆保存在该变量中,然后让这个变量告诉我们这个圆的面积和在该变量中,然后让这个变量告诉我们这个圆的面积和周长是多少周长是多少 以
6、计算圆的面积和周长的问题为例以计算圆的面积和周长的问题为例裳队巢惫体泻弃风蒲筛篇仁瘤痈光焙字颇钉钵面卫扳境耻挑跳驹凿闯茧啊第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 6从面向过程到面向对象从面向过程到面向对象v抽象的过程抽象的过程 v面向对象的程序设计的特点面向对象的程序设计的特点 v库和类库和类 嗽畸漓且抡晤胶厘裴囤桩痞埂滤振毋顽赏狼霞渤廉酚杠慌售善庇椎唐浆秦第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 7面向对象的程序设计的特点面向对象的程序设计的特点 v代码重用:圆类型也可以被那些也需要处代码重用:圆类
7、型也可以被那些也需要处理圆的其他程序员使用理圆的其他程序员使用 v实现隐藏:实现隐藏:类的创建者创造新的工具类的创建者创造新的工具类的使用者则收集已有的工具快速解决所需解类的使用者则收集已有的工具快速解决所需解决的问题决的问题这些工具是如何实现的,类的使用者不需要知这些工具是如何实现的,类的使用者不需要知道道 膝迟腮辑域脐倘毅酗对府部太贸似著瑞江临奥骋丸逊兄劲切芝哭族倚芦廖第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 8面向对象的程序设计的特点面向对象的程序设计的特点v继承:在已有工具的基础上加以扩展,形成一个功能继承:在已有工具的基础上加以扩展,形成
8、一个功能更强的工具。如在学校管理系统中,可以形成如下的更强的工具。如在学校管理系统中,可以形成如下的继承关系继承关系 人人教师教师学生学生教辅教辅高级高级中级中级初级初级本科本科硕士硕士博士博士实验室实验室行政行政攒敷叉撼徐锣谰梦击堰刑衷菱颠托狱掣殉铲内纹税卿惯黄冈洪怂塑聊琴戮第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 9面向对象的程序设计的特点面向对象的程序设计的特点v多态性:多态性:当处理层次结构的类型时,程序员往往想把各个层次的当处理层次结构的类型时,程序员往往想把各个层次的对象都看成是基类成员。对象都看成是基类成员。如需要对教师进行考核,不必
9、管他是什么职称,只要向如需要对教师进行考核,不必管他是什么职称,只要向所有教师发一个考核指令。每位教师自会按照自己的类所有教师发一个考核指令。每位教师自会按照自己的类型作出相应的处理。如高级职称的教师会按高级职称的型作出相应的处理。如高级职称的教师会按高级职称的标准进行考核,初级职称的教师会按初级职称的标准进标准进行考核,初级职称的教师会按初级职称的标准进行考核。行考核。v好处:程序代码就可以不受新增类型的影响。如增加一个好处:程序代码就可以不受新增类型的影响。如增加一个院士的类型,它也是教师类的一个子类,整个程序不用修院士的类型,它也是教师类的一个子类,整个程序不用修改,但功能得到了扩展。改
10、,但功能得到了扩展。韵钳录缆蓝郧坞皱廖坷涣司破纳默爱彰邯旦羹醉单液唆殊斋腑罢虾千锡鸭第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 10从面向过程到面向对象从面向过程到面向对象v抽象的过程抽象的过程 v面向对象的程序设计的特点面向对象的程序设计的特点 v库和类库和类 搁们篷锹号旧皋录誊雾孵针结简漠羹别雪虾卷醋杨县江屑井耿辰厌拆其循第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 11库和类库和类 v类是更合理的库类是更合理的库 v例:设计一个库,提供动态实型数组服例:设计一个库,提供动态实型数组服务,该数组满足两个要
11、求:务,该数组满足两个要求:可以任意指定下标范围;可以任意指定下标范围;下标范围可在运行时确定;下标范围可在运行时确定;使用下标变量时会检查下标的越界。使用下标变量时会检查下标的越界。访滥心檬葫疼勃扮桨泊惜巍我躬感号豌嗜符际削壹继圭私媚受姜绕山蹬歌第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 12库的设计库的设计v数组的保存数组的保存数组需要一块保存数组元素的空间。这块空间需数组需要一块保存数组元素的空间。这块空间需要在执行时动态分配。要在执行时动态分配。数组的下标可以由用户指定范围。因此,对每个数组的下标可以由用户指定范围。因此,对每个数组还需要保存
12、下标的上下界。数组还需要保存下标的上下界。保存这个数组的三个部分是一个有机的整体,因保存这个数组的三个部分是一个有机的整体,因此可以用一个结构体把它们封装在一起。此可以用一个结构体把它们封装在一起。v数组操作数组操作给数组分配空间给数组分配空间给数组元素赋值给数组元素赋值取某一个数组元素的值取某一个数组元素的值由于这个数组的存储空间是动态分配的,因此,由于这个数组的存储空间是动态分配的,因此,还必须有一个函数去释放空间还必须有一个函数去释放空间 丝勇霖颇役莉柑嘶幌瘤绑泰驹须舰记霜叁启花同钮刮辕汤败纸坞庆遵祥憋第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 -
13、 13Array库的头文件库的头文件#ifndef _array_h#define _array_h/可指定下标范围的数组的存储struct DoubleArray int low; int high; double *storage;肌订雁膛妨肤距殷赊楚纵僚筋块悠畸翅投柬件绍鳞凋流宅涵摔演齐廷践渺第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 14/根据根据low和和high为数组分配空间为数组分配空间bool initialize(DoubleArray &arr, int low, int high);/设置数组元素的值设置数组元素的值bool i
14、nsert(const DoubleArray &arr, int index, double value);/取数组元素的值取数组元素的值bool fatch(const DoubleArray &arr, int index, double &value);/回收数组空间回收数组空间void cleanup(const DoubleArray &arr);#endif 贝羞蛰骑僵韭诡何客验蛋护雪恃布酸弟趋查旨迫县饰挎殴娠翠鼠臻旭抓桅第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 15Array库的实现文件库的实现文件#include array.h#
15、include using namespace std;bool initialize(DoubleArray &arr, int low, int high) arr.low = low; arr.high = high; arr.storage = new double high - low + 1; if (arr.storage = NULL) return false; else return true;泪纲估磊脑镐酷韭锁阻署巧邹缀肢夹叔俘弘么癣秸螟姆克顶阐空搓仍江逝第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 16bool insert(c
16、onst DoubleArray &arr, int index, double value) if (index arr.high) return false; arr.storageindex - arr.low = value; return true;bool fatch(const DoubleArray &arr, int index, double &value) if (index arr.high) return false; value = arr.storageindex - arr.low ; return true;void cleanup(const DoubleA
17、rray &arr) delete arr.storage; 逛草闷初陵州模榨风有趾玲杰蚁幅毅菌缄荫汀竞然版报抑矩汞聋荒简馁滔第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 17Array库的应用库的应用#include using namespace std;#include array.h int main() DoubleArray array; double value; int low, high, i; cout low high; if (!initialize(array, low, high) cout 空间分配失败空间分配失败 ; r
18、eturn 1; 愿徽坍防磅滇石速请少呛碌穆南企瞄奴捐挛俱竣抢扮棘算诲肢暂夕绷舍檄第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 18for (i = low; i = high; +i) cout 请输入第请输入第 i value; insert(array, i, value); while (true) cout i; if (i = 0) break; if (fatch(array, i, value) cout value endl; else cout 下标越界下标越界n; cleanup(array); return 0; 缆翟哮氮励钢谁
19、搁才叙晴猩镐啄粒蹭顾赞如介遣迹岳州液还御胚陪涧斟势第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 19Array库的问题库的问题v这个数组的使用相当笨拙。每次调用和数组有关的函数这个数组的使用相当笨拙。每次调用和数组有关的函数时,都要传递一个结构体给它。时,都要传递一个结构体给它。v我们可能在一个程序中用到很多库,每个库都可能需要我们可能在一个程序中用到很多库,每个库都可能需要做初始化和清除工作。库的设计者都可能觉得做初始化和清除工作。库的设计者都可能觉得initialize和和cleanup是比较合适的名字,因而都写了这两个函数。是比较合适的名字,因而
20、都写了这两个函数。v系统内置的数组在数组定义时就指定了元素个数,系统系统内置的数组在数组定义时就指定了元素个数,系统自动会根据元素个数为数组准备存储空间。而我们这个自动会根据元素个数为数组准备存储空间。而我们这个数组的下标范围要用数组的下标范围要用initialize函数来指定,比内置数组多函数来指定,比内置数组多了一个操作。了一个操作。v当数组使用结束后,还需要库的用户显式地归还空间。当数组使用结束后,还需要库的用户显式地归还空间。v对数组元素的操作不能直接用下标变量的形式表示。对数组元素的操作不能直接用下标变量的形式表示。 蚁椒冈督菠呵陵朋卫疟挽鸭愿歹拦叙捧肚奏辆待葛爽搁匪稼肺师圣见梁与第
21、10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 20Array库的改进库的改进v将函数放入结构体将函数放入结构体 v好处:好处:函数原型中的第一个参数不再需要。编译函数原型中的第一个参数不再需要。编译器自然知道函数体中涉及到的器自然知道函数体中涉及到的low, high和和storage是同一结构体变量中的成员是同一结构体变量中的成员函数名冲突的问题也得到了解决。现在函函数名冲突的问题也得到了解决。现在函数名是从属于某一结构体,从属于不同结数名是从属于某一结构体,从属于不同结构体的同名函数是不会冲突的。构体的同名函数是不会冲突的。溉釉全应远茬三入绷帖执圣公
22、旺客语城晒哼锭品铁厉箩劣元坯选晤枷均适第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 21改进后的改进后的Array库的头文件库的头文件#ifndef _array_h#define _array_hstruct DoubleArray int low; int high; double *storage; bool initialize(int lh, int rh); bool insert(int index, double value); bool fatch(int index, double &value); void cleanup();#
23、endif 函数都瘦身了!函数都瘦身了!径沙铰琶忿夸匿山师鸟抨槐栖纳巨僳乒潜还涧滓怎努盲贰呀理幼胀摄耀耙第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 22改进后的改进后的Array库的实现文件库的实现文件v与原来的实现有一个变化:函数名前要加与原来的实现有一个变化:函数名前要加限定限定bool IntArray:initialize(int lh, int rh)low = lh; high = rh; storage = new double high - low + 1; if (storage = NULL) return false; else
24、 return true; 珠捣刺逼趟隐移墒堤沽信歌劲轨绍阁拍甄追凿浊躯挣淘胁桥亦讨颇要沟惟第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 23改进后的改进后的Array库的应用库的应用v函数的调用方法不同。就如引用结构体函数的调用方法不同。就如引用结构体的成员一样,要用点运算符引用这些函的成员一样,要用点运算符引用这些函数数 过孪迈麦庞九蟹型监兹差榜拭汾宽描氏望恋厨外依伎尉破险箍比仲些甜娩第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 24#include using namespace std;#include
25、 array.h“int main() DoubleArray array; double value; int low, high, i; cout low high; if (!array.initialize(low, high) cout 空间分配失败空间分配失败 ; return 1; 藏探酿暴铅搪轴爬求饼兵帕戮钻俊隔腑讳忍袖锯直揉粱参蔑闲爽材殉业特第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 25for (i = low; i = high; +i) cout 请输入第请输入第 i value; array.insert(i, value)
26、; while (true) /数组元素的查找数组元素的查找 cout i; if (i = 0) break; if (array.fatch(i, value) cout value endl; else cout 下标越界下标越界n; array.cleanup(); return 0; 扬碉理铜部煽致碗毅析呐斥怜识少噎茁介炮痈吐瓮用躲丧疆码呈问栏缎奶第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 26将函数放入结构体的意义将函数放入结构体的意义v将函数放入结构体是从将函数放入结构体是从C到到C+的根本改变的根本改变v在在C中,结构体只是将一组相关
27、的数据捆绑了起中,结构体只是将一组相关的数据捆绑了起来,它除了使程序逻辑更加清晰之外,对解决问来,它除了使程序逻辑更加清晰之外,对解决问题没有任何帮助。题没有任何帮助。v将处理这组数据的函数也加入到结构体中,结构将处理这组数据的函数也加入到结构体中,结构体就有了全新的功能。它既能描述属性,也能描体就有了全新的功能。它既能描述属性,也能描述对属性的操作。事实上,它就成为了和内置类述对属性的操作。事实上,它就成为了和内置类型一样的一种全新的数据类型。型一样的一种全新的数据类型。v为了表示这是一种全新的概念,为了表示这是一种全新的概念,C+用了一个新用了一个新的名称的名称 类来表示。类来表示。孪阶包
28、焊醒动哨笑柞亲轰舜剪癌篙撤壹芭必肃烯贱慎协闪捍憎风鞋涵职辈第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 27第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 厉祭壬捌忽媳厘桥臭埋眶鉴彻气颊疼杯你任某捡闸耽僵鹏钵滩杏让孤药炽第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 201
29、1.9程序设计 - 28类定义的一般格式vclass 类名类名 private: 私有数据成员和成员函数私有数据成员和成员函数 public: 公有数据成员和成员函数公有数据成员和成员函数 ; 繁岛蛤呜竞乓纸楔晕咳霓择烬锤拱蕉蔚漾莹余此躺珊墙漂僚踢赣夯盏窝讲第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 29公有和私有成员v私有成员私有成员(private):只能由类的成员函:只能由类的成员函数调用数调用v公有成员公有成员(public):类的用户可以调用:类的用户可以调用的信息,是类对外的接口的信息,是类对外的接口v私有成员被封装在一个类中,类的用户私
30、有成员被封装在一个类中,类的用户是看不见的是看不见的战五民凤卿讥瘴甫漓拴往莫凹素掂再囱美鸟秀众晓警情臭喧迅漫限滩顿索第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 30DoubleArray类的定义类的定义class DoubleArray private: int low; int high; double *storage;public: bool initialize(int lh, int rh); bool insert(int index, double value); bool fatch(int index, double &value)
31、; void cleanup();锈丈醉旁作惮队万跳墓饮像蚕乞递坡则愤腐系胶竹戳迅责露呈诧冤肯监坷第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 31类定义说明vprivate 和和public的出现次序可以是任意的。的出现次序可以是任意的。也可以反复出现多次。也可以反复出现多次。v成员还可以被说明为成员还可以被说明为protectedv数据成员一般说明为数据成员一般说明为private,需要被用户,需要被用户调用的函数说明为调用的函数说明为public狸富建收导载左豌式纸犊和辛同渭脏臆晾嫡灶扶踌磐瑶距选泰订沛摸揭橡第10部分创建功能更强的类型程序设计程
32、序设计 cs.sjtu 2011.9程序设计 - 32接口和实现分开接口和实现分开v与库设计一样,类的定义写在接口文件与库设计一样,类的定义写在接口文件中,成员函数的实现写在实现文件中。中,成员函数的实现写在实现文件中。v某些简单的成员函数的定义可以直接写某些简单的成员函数的定义可以直接写在类定义中。在类定义中。v在类定义中定义的成员函数被认为是内在类定义中定义的成员函数被认为是内联函数。联函数。糠堂们譬凯垂顾绽逆惟迈株吕衅橱眠捣兰挝涅寸茸遵咬携觅吴课基辕劝拔第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 33类定义实例类定义实例v试定义一个有理数类,该
33、类能提供有理试定义一个有理数类,该类能提供有理数的加和乘运算。要求保存的有理数是数的加和乘运算。要求保存的有理数是最简形式。如最简形式。如2/6应记录为应记录为1/3。 噬怠陛疲诡奏荒显缅区馏陨养绊橇靳铜照橡卑翘诀锑扶读鼠屁查拟东设留第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 34设计考虑设计考虑v保存有理数:保存一个有理数就是保存两个整数。保存有理数:保存一个有理数就是保存两个整数。v有理数类的操作:有理数类的操作:加函数加函数乘函数乘函数创建有理数的函数,用以设置有理数的分子和分母创建有理数的函数,用以设置有理数的分子和分母输出有理数函数输出有理
34、数函数化简函数化简函数v访问权限设计:访问权限设计:数据成员是私有的数据成员是私有的化简函数是内部调用的函数,与用户无关,因此也是私有的化简函数是内部调用的函数,与用户无关,因此也是私有的其他函数都是公有的其他函数都是公有的盲职炼宪耸钧宁贪酮识送哭帛报索蓬巴玲蹋瞒皮翻泰阂座疽车涪示臣封珠第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 35#ifndef _rational_h#define _rational_h#include using namespace std;class Rational private:int num;int den;void
35、 ReductFraction(); /将有理数化简成最简形式将有理数化简成最简形式public:void create(int n, int d) num = n; den = d; void add(const Rational &r1, const Rational &r2); void multi(const Rational &r1, const Rational &r2);void display() cout num / den) ? den : num; for (; tmp 1; -tmp) if (num % tmp = 0 & den % tmp =0) num /= t
36、mp; den /= tmp; break;枫卞彼鼠概痞雨腕弃绰林亏嗣杭淬核峦寂亥克涝哆枯虫钻等条嘿棘编纺托第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 38第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 氮侨寐刃戚阵厘摩灰技骑椭糕帛般氦限沤边很杠舀置缸赛哭菜站荆戈凰抿第10部分创建功能
37、更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 39对象的定义v类与对象的关系:类型与变量的关系类与对象的关系:类型与变量的关系v对象定义方法:对象定义方法:直接在程序中定义某个类的对象直接在程序中定义某个类的对象存储类别存储类别 类名类名 对象列表;对象列表;如定义两个如定义两个IntArrayIntArray类的对象类的对象arr1arr1和和arr2arr2,可写,可写成:成:IntArray arr1, arr2;IntArray arr1, arr2;用动态内存申请的方法申请一个动态对象。用动态内存申请的方法申请一个动态对象。 Rational *rp;Rp =
38、 new Rational; rp = new Rational20; delete Rp;或delete rp;觉崇傅佰亨躇宗瑞孟痞稼卓痰寓挛鹃洱苔凰磕株颗傀藉缆浑匀畦枣饼积峨第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 40对象的引用v对象名对象名.数据成员名数据成员名 或或 对象指针对象指针-数据成员名数据成员名 arr1.storage 或或 rp-numv对象名对象名.成员函数名(实际参数表)成员函数名(实际参数表) 或或对象指针对象指针-成员函数名(实际参数表)成员函数名(实际参数表) arr1.insert() 或或 rp-add()v外
39、部函数不能引用对象的私有成员外部函数不能引用对象的私有成员骄晓照匹幢骋关皱映泉分义历翟疗滁蓉钵咐像戏隋饯目渭唱喀氰璃掐愧茹第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 41有理数类的使用有理数类的使用#include using namespace std;#include Rational.h /使用有理数类使用有理数类int main() int n, d; Rational r1, r2, r3; /定义三个有理数类的对象定义三个有理数类的对象 计算两个有理数的和与积计算两个有理数的和与积 超暂碰耪犁见迎颗李檄箭钦谆拳侮陵塞纱大向我受诬揖什曝刮开
40、怕煞慌陷第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 42 cout n d; r1.create(n,d); cout n d; r2.create(n,d); r3.add(r1, r2); /执行执行r3=r1+r2 r1.display(); cout + ; r2.display(); cout = ; r3.display(); cout endl; r3.multi(r1, r2); /执行执行r3=r1*r2 r1.display(); cout * ; r2.display(); cout = ; r3.display(); cout
41、 num = n; this-den = d;钦栈欺契周高喀矽裳肯冯搓研丰栽兆拼楼亮漫熄犹铝抱舰绢宾徐炉璃硫着第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 46this指针指针v通常,在写成员函数时可以省略通常,在写成员函数时可以省略this,编译,编译时会自动加上它们。时会自动加上它们。v如果在成员函数中要把对象作为整体来访问如果在成员函数中要把对象作为整体来访问时,必须显式地使用时,必须显式地使用this指针。这种情况常指针。这种情况常出现在函数中返回一个对调用函数的对象的出现在函数中返回一个对调用函数的对象的引用,引用, 誊嘲蠕幕材态攒枷卢锦藩胚
42、擂呛忧砌澄物后论莽无丰皂寅冉末纲橙矽捶枯第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 47第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 许叭姨棺输垃紧娩伍砾泄俊函惋囱母爽衙饰张挞呻拴捍栅妨咽颜愧朵唐庐第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 -
43、 48对象的构造与析构对象的构造与析构v某些类的对象,必须在对它进行了初始化以后某些类的对象,必须在对它进行了初始化以后才能使用。才能使用。v对于某些类的对象在消亡前,往往也需要执行对于某些类的对象在消亡前,往往也需要执行一些操作,做一些善后的处理。一些操作,做一些善后的处理。v初始化和扫尾的工作给类的用户带来了额外的初始化和扫尾的工作给类的用户带来了额外的负担,使他们觉得类和内置类型还是不一样。负担,使他们觉得类和内置类型还是不一样。v用户希望使用类的对象就和使用内置类型的变用户希望使用类的对象就和使用内置类型的变量一样,一旦定义了,就能直接使用。用完了,量一样,一旦定义了,就能直接使用。用
44、完了,由系统自动回收。由系统自动回收。腐链爆埠眩戈荣及佑莹蒋蓝换蛰级示菩怯骚额嘱撵甫疹塔巡呐笑偷臻度仲第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 49构造函数与析构函数v构造函数和析构函数是特殊的成员函数构造函数和析构函数是特殊的成员函数v构造函数:对数据成员进行初始化。构造函数:对数据成员进行初始化。v析构函数:执行与构造函数相反的操作,析构函数:执行与构造函数相反的操作,通常执行一些清理工作,如释放分配给通常执行一些清理工作,如释放分配给对象的动态空间等。对象的动态空间等。决公半捻晶慈邵暗浆绽牢斜搜猩蹬稍主量扬霄垄猩慌阔搞隶泌敷肠佬砖庶第10部分
45、创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 50构造函数的特点v定义对象时,系统会自动调用构造函数。定义对象时,系统会自动调用构造函数。v构造函数的名字必须与类名相同构造函数的名字必须与类名相同v构造函数可以有任意类型的参数,也可以不带参数,但构造函数可以有任意类型的参数,也可以不带参数,但不能具有返回类型。因此在定义构造函数时,不能说明不能具有返回类型。因此在定义构造函数时,不能说明它的类型,甚至说明为它的类型,甚至说明为void类型也不行。类型也不行。v如果没有给类定义构造函数,编译系统会自动生成一个如果没有给类定义构造函数,编译系统会自动生成一个缺省的构
46、造函数。它只为对象开辟存储空间,空间中的缺省的构造函数。它只为对象开辟存储空间,空间中的内容为随机数。内容为随机数。v构造函数可以重载构造函数可以重载勒落夺肯饯遗誓咏斥干仲擦套搁兰漳斤颁浙找践淌雾镐冬阑曳邦矛渍论长第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 51构造函数实例构造函数实例v如如DoubleArray类需要有一个构造函数,该函类需要有一个构造函数,该函数可定义为数可定义为 DoubleArray(int lh, int rh) low = lh; high = rh; storage = new double high low + 1;
47、有了构造函数,就不需要有了构造函数,就不需要initialize函数了。以函数了。以在定义时有在定义时有C+自动完成初始化工作。自动完成初始化工作。v定义对象时,须指定构造函数的实际参数定义对象时,须指定构造函数的实际参数 DoubleArray array(20, 30);次鳖颈灸吴础盂泅拘燃肄莫胁疙塘测亦胶文君韦牟储镇农耕半端佐氨终嗜第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 52构造函数实例构造函数实例vRational类不一定要有构造函数,但习惯上应改类不一定要有构造函数,但习惯上应改为每个类定义一个构造函数,以便在需要时对对为每个类定义一个
48、构造函数,以便在需要时对对象进行初始化象进行初始化vRational类构造函数可定义为类构造函数可定义为 Rational(int n1, int n2) num = n1; den = n2; ReductFraction(); v定义对象时,须指定构造函数的实际参数。例定义对象时,须指定构造函数的实际参数。例 Rational r(2, 7);扇荡痪叠第棚悼诅郝卉氮帅聂活静辈惊陪忆谴盏衅嚎嫁值再护挥通伺熬生第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 53构造函数的使用构造函数的使用v有了构造函数后,对象定义的一般形式为:有了构造函数后,对象定义的
49、一般形式为: 类名类名 对象名(实际参数表);对象名(实际参数表); 其中,实际参数表必须和该类的某一个构造函其中,实际参数表必须和该类的某一个构造函数的形式参数表相对应。数的形式参数表相对应。v除非这个类有一个构造函数是没有参数的,那除非这个类有一个构造函数是没有参数的,那么可以用:么可以用: 类名类名 对象名;对象名;v不带参数的构造函数称为默认的构造函数。不带参数的构造函数称为默认的构造函数。v一般每个类应该有一个缺省的构造函数一般每个类应该有一个缺省的构造函数 橇陇魏沼围琐汉谐戚耶簧钥孝蛛背奋球婿一俞荒汛灸禾合信孪睡廉歌辑恼第10部分创建功能更强的类型程序设计程序设计 cs.sjtu
50、2011.9程序设计 - 54带缺省值的带缺省值的Rational类的构造函数类的构造函数vRational(int n1 = 0, int n2 = 1)Rational(int n1 = 0, int n2 = 1) num = n1; den = n2; num = n1; den = n2; ReductFraction(); ReductFraction(); v表示缺省情况下,构造的是一个值为表示缺省情况下,构造的是一个值为0 0的有理数。的有理数。此时,定义此时,定义 Rational r1(3,5), r2; Rational r1(3,5), r2; 是正确的是正确的鹰计卖交
51、伪氧氢稚托挠快珐愤裸搏刊一浇柴澳队苫书奇冯办赛法叶鸽儡篙第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 55动态对象的初始化动态对象的初始化 v动态变量的初始化是在类型后面用一个圆动态变量的初始化是在类型后面用一个圆括号指出它的实际参数表括号指出它的实际参数表v如果要为一个动态的如果要为一个动态的DoubleArray数组指数组指定下标范围为定下标范围为20到到30,可用下列语句:,可用下列语句: p = new DoubleArray(20, 30);v括号中的实际参数要和构造函数的形式参括号中的实际参数要和构造函数的形式参数表相对应。数表相对应。厢苯
52、巨爵铆筐孵寥冲藕醋捧捶令实盅箭名秃狙垃嘉抢渣详酸代糯懂脯赣购第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 56初始化列表方法v构造函数还有一个与普通函数不同的地方,就是可以构造函数还有一个与普通函数不同的地方,就是可以包含一个构造函数初始化列表。包含一个构造函数初始化列表。v构造函数初始化列表位于函数头和函数体之间。它以构造函数初始化列表位于函数头和函数体之间。它以一个冒号开头,接着是一个以逗号分隔的数据成员构一个冒号开头,接着是一个以逗号分隔的数据成员构造列表造列表v如如DoubleArray的构造函数可写为的构造函数可写为 DoubleArray
53、: DoubleArray(int lh, int rh) : low(lh), high(rh) storage = new double high - low + 1; 恶懦劳祟尽尹亥昏教彬幕烂粱胸卜惑婴兼袖瓶大极持摘咽翔哪昔涟瞳施维第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 57为什么要使用初始化列表为什么要使用初始化列表 v对象的构造过程:对象的构造过程:执行每一个数据成员的构造函数。如果成员没有出现执行每一个数据成员的构造函数。如果成员没有出现在初始化列表中,执行默认的构造函数,否则按初始在初始化列表中,执行默认的构造函数,否则按初始化列表
54、中列出的实际参数执行对应的构造函数化列表中列出的实际参数执行对应的构造函数执行类的构造函数执行类的构造函数v利用初始化列表可以提高构造函数的效率。在初利用初始化列表可以提高构造函数的效率。在初始化数据成员的同时完成了赋初始的工作。始化数据成员的同时完成了赋初始的工作。我们完全可以在函数体内对数据成员赋初值我们完全可以在函数体内对数据成员赋初值 !厅扯驼舟愉屋纸后姐蛙掠狙簧惠炙省闯楷娩炯冒译痊债域嘻浆时侵战航适第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 58重载构造函数v构造函数可以重载,导致对象可以有构造函数可以重载,导致对象可以有多种方式构造多种方
55、式构造v试设计一个时间转换器,用户可输入试设计一个时间转换器,用户可输入秒、分秒或时分秒输出相应的秒数。秒、分秒或时分秒输出相应的秒数。茬蔫援累剿导首园卯酮酸漱哦捧围辈纳婉潜硅庐婶琢芒赎蝎普文骋膏认夜第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 59时间转换器的实现#include Using namespace std;class timer int second; public: timer(int t) second = t; timer(int min, int sec) second = 60 * min + sec; timer(int h
56、, int min, int sec) second=sec+60*min+3600*h; int gettime() return second; main()timer a(20), b(1, 20), c(1, 1, 10); cout a.gettime() endl; cout b.gettime() endl; cout c.gettime() endl;龙戏谣瓶轧捎查鞍脱过瑚声事围种迭荒拢枪盾肝刚盏伎磨摘候孜拣葡幌纠第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 60析构函数v析构函数在撤销对象时,完成一些善后析构函数在撤销对象时,完成一些
57、善后工作,由编译系统自动调用工作,由编译系统自动调用v析构函数与构造函数名字相同,但它前析构函数与构造函数名字相同,但它前面必须加一个波浪号(面必须加一个波浪号()v析构函数没有参数,没有返回值,也不析构函数没有参数,没有返回值,也不能重载。能重载。v若定义类时没有定义析构函数,编译系若定义类时没有定义析构函数,编译系统会自动生成一个缺省的空析构函数统会自动生成一个缺省的空析构函数肄灌箭峭举侮抬八笔契趣倘窥替诉句打毯州坝峦瓦车懈勋嘛仗添诸宦吼厢第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 61析构函数析构函数v并不是每个类都必须要有析构函数,如并不是每
58、个类都必须要有析构函数,如Rational类就不需要析构函数。类就不需要析构函数。v一般在构造函数中有动态申请内存的,必一般在构造函数中有动态申请内存的,必须有析构函数。如须有析构函数。如DoubleArray类,必须类,必须有析构函数释放有析构函数释放storage指向的空间。有指向的空间。有了析构函数,就不需要了析构函数,就不需要cleanup函数了函数了攻曙惧门立廉护桨堤又费陷鄂集巨黑甩坤泣营扫厉敝镊铆疙执缅孩颂揽标第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 62析构函数举例class DoubleArray int low; int high
59、; double *storage;public: DoubleArray(int lh, int rh):low(lh), high(rh) storage = new double high - low + 1; bool insert(int index, double value); bool fatch(int index, double &value); DoubleArray() delete storage; ; 雾路燃缺请斋瘩蓉科实了饰漆斡蝗司臂兜春汲模拱耗惹咯尝薯郊饵锁魔影第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 63Doubl
60、eArray类的使用类的使用#include using namespace std;#include DoubleArray.hint main() DoubleArray array(20,30); int i; double value; for (i=20; i=30; +i) cout 请输入第请输入第 i value; array.insert(i, value); while (true) cout i; if (i = 0) break; if (array.fatch(i, value) cout value endl; else cout 下标越界下标越界n; return
61、 0; 驰蚕似芦惩饲赶覆裁党洁识惑伯悄仕掸草棘烃牲詹带厕蜗爷这腥诛疙娇你第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 64拷贝构造函数v在创建一个对象时,可以用一个同类的对象对在创建一个对象时,可以用一个同类的对象对其初始化。这是需要调用一个特殊的构造函数,其初始化。这是需要调用一个特殊的构造函数,称为拷贝构造函数。称为拷贝构造函数。v拷贝构造函数以一个同类对象引用作为参数,拷贝构造函数以一个同类对象引用作为参数,它的原型为:它的原型为: 类名(类名(const &););v用户可以根据自己的需要定义拷贝构造函数用户可以根据自己的需要定义拷贝构造函数细
62、寒琳寅僧泼吞绰衅开难乃馆送怎式碌矿树钩洒碾刺诵舔谤涨富添与悠辩第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 65缺省的拷贝构造函数v如果用户没有定义拷贝构造函数,系统如果用户没有定义拷贝构造函数,系统会定义一个缺省的拷贝构造函数。该函会定义一个缺省的拷贝构造函数。该函数将已存在的对象原式原样地复制给新数将已存在的对象原式原样地复制给新成员成员霉砸撤梭凡秘板诫直韦愉茎矮碉笔级诣捡瓢镣懂午遮湖毛雁伞议域柠绸益第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 66自定义拷贝构造函数Classname(const clas
63、sname &ob)/.例:例:Class point int x, y; public: point(int a, int b) x = a; y = b; point(const point &p) x = 2 * p.x; y = 2 * p.y;夜谈撂闺突益舟辞询谨荣球佑轴侍烤唬余樱疲窑致惮泻桐殆镍岛署爵恼岛第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 67何时需要自定义拷贝构造函数何时需要自定义拷贝构造函数v一般情况下,默认的拷贝构造函数足以满足要求。一般情况下,默认的拷贝构造函数足以满足要求。v但某些情况下可能需要设计自己的拷贝构造函数。但
64、某些情况下可能需要设计自己的拷贝构造函数。v例如,我们希望对例如,我们希望对DoubleArray类增加一个功能,能够定类增加一个功能,能够定义一个和另一个数组完全一样的数组。但默认的拷贝构义一个和另一个数组完全一样的数组。但默认的拷贝构造函数却不能胜任。如果正在构造的对象为造函数却不能胜任。如果正在构造的对象为arr1,作为参,作为参数的对象是数的对象是arr2,调用默认的拷贝构造函数相当于执行下,调用默认的拷贝构造函数相当于执行下列操作:列操作: arr1.low = arr2.low; arr1.high = arr2.high; arr1.storage = arr2.storage;
65、 前两个操作没有问题,第三个操作中,前两个操作没有问题,第三个操作中,storage是一个指是一个指针,第三个操作意味着使针,第三个操作意味着使arr1的的storage指针和指针和arr2的的storage指针指向同一块空间。指针指向同一块空间。 诱馒褪捻强敝傻烷外罩绞辛于挨酸木遭伦属沤凭颈诱伤醋俄戎账潍杯廖吊第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 68使用同一块空间的问题使用同一块空间的问题v一个对象的修改将会影响另一个对象一个对象的修改将会影响另一个对象v如果两个对象的作用域不同,当一个对如果两个对象的作用域不同,当一个对象析构时,另一个对
66、象也将丧失它的空象析构时,另一个对象也将丧失它的空间间绣戍伟答盾祝驰吕滓元你汤巍颜遗药端刊逾塌戮升酋粳赦扼皮咯崩风秸祖第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 69DoubleArray类的拷贝构造函数类的拷贝构造函数DoubleArray(const DoubleArray &arr) low = arr.low; high = arr.high; storage = new double high low + 1; for (int i = 0; i high low + 1; +i) storagei = arr.storagei; 析臆航粱
67、饮纱蹭务摄园过怒不凑镍撒津灌辨依贵柏辣本瓶窜深砰垮泣肤硒第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 70拷贝构造函数的应用场合拷贝构造函数的应用场合v对象定义时对象定义时 v函数调用时,把对象作为参数传给值函数调用时,把对象作为参数传给值传递的形式参数传递的形式参数v把对象作为返回值时把对象作为返回值时 藉映茅絮阎粤著王红撞旋合妓痪孵堵穿贯碱盐牡楔猿兴斑棠宰绰履婴涎跳第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 71对象定义时对象定义时v将初始值放在圆括号中,直接调用与实参类将初始值放在圆括号中,直接调用与实
68、参类型相匹配的构造函数。如型相匹配的构造函数。如 DoubleArray array2(array1);v用用“=”符号符号 DoubleArray array = array1; 勒刽衰巧淄速凡谦署佳逢乱尊各针她尿柿主嘻布壳友逗祥窥复诬翠噪羞貌第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 72自定义拷贝构造函数举例class point int x, y; public: point(int a, int b)x=a; y=b; point(const point &p) x=2*p.x; y=2*p.y; void print() coutx ye
69、ndl;void main()point p1(10, 20), p2(p1), p3 = p1, p4(1, 2); p1.print(); p2.print(); p3.print(); p4.print(); p4 = p1; p4.print(); 1020204020 401210 20秀尘欧舵擦留骏商铁蛋厘霞搐狗包灯写遣礼驮容玉务恭彩豺趴熄造赶镑酞第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 73把对象作为参数传给函数时把对象作为参数传给函数时 v如有函数:如有函数:void f(DoubleArray array);v函数调用函数调用 f
70、(arr); 将创建一个形式参数对象将创建一个形式参数对象array,并调用,并调用拷贝构造函数用对象拷贝构造函数用对象arr初始化初始化arrayv注意:如果是引用传递就没有这个构造过注意:如果是引用传递就没有这个构造过程了程了袱巢撂柴肛畦养墓媳吨院椅裂黑矢赔躁涉桅荣康戍微哈基祟童幅囤硒肥耕第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 74把对象作为返回值时把对象作为返回值时 v如有函数如有函数 DoubleArray f() DoubleArray a; return a; v当执行到当执行到return语句时,会创建一个语句时,会创建一个Doub
71、leArray类的临时对象,并调用拷贝构造函数用对象类的临时对象,并调用拷贝构造函数用对象a初始初始化该临时对象,并将此临时对象的值作为返回值。化该临时对象,并将此临时对象的值作为返回值。 彬薛浑面浦丰萨倘缓姐其臻倾瓢尖历扳怎栋滔蔓罕孜蕉永渗聪揽渊伦妇硫第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 75类变量的生命周期类变量的生命周期v与普通的内置类型的变量完全相同与普通的内置类型的变量完全相同Time gTime;int main() Time lTime1;static Time sTime;Time lTime2;创建顺序:遇到变量定义时调用构造
72、函数1、gTime构造函数 2、lTime1构造函数 3、sTime构造函数 4、lTime2构造函数抖琐鳖宫骑官灵烯玖畸参蜒蛔砖谁划那扮讶甫承竞轨耶慌阁碧嗅堪仁爷辽第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 76类变量的生命周期类变量的生命周期Time gTime;int main()Time lTime1;static Time sTime;Time lTime2;消失顺序:1、局部变量先消失,然后是静态局部变量, 最后是全局变量;2、后创建的先消失;1、lTime2析造函数 2、lTime1析造函数3、sTime析造函数 4、gTime2析造函
73、数篇菠韦葫档以粗合田薪云处壤具需根躇坍宛扛岛晚枪祈荧廷浆陌注辽守得第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 77变量生命周期的验证变量生命周期的验证CreateAndDestroy类定义类定义class CreateAndDestroy public: CreateAndDestroy( int, string ); CreateAndDestroy(); private: int objectID; ; 傍卤椰悟略忿式铝握吴背鳃劣躲砾怯得线掀臻津齐震尼屁湿猩筋窖涂枝卵第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设
74、计 - 78CreateAndDestroy:CreateAndDestroy( int ID) objectID = ID; cout Object objectID constructor runs endl;CreateAndDestroy:CreateAndDestroy() cout Object objectID destructor runs endl; 州募碾泼取景身柏碧独晃题包胶授霞昆呀即疯沤庙巢费漠恍袁雇灶阂禄獭第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 79CreateAndDestroy first( 1); int main
75、() cout nMAIN FUNCTION: EXECUTION BEGINS endl; CreateAndDestroy second( 2); static CreateAndDestroy third( 3,); create(); cout nMAIN FUNCTION: EXECUTION RESUMES endl; CreateAndDestroy fourth( 4); cout nMAIN FUNCTION: EXECUTION ENDS endl; return 0;用户程序用户程序甫拓邹侯黄宵磅蕊项窝技考新啃者几韧娶临蓬犹剐脊拢干哇挪索侍诬艰于第10部分创建功能更强的类
76、型程序设计程序设计 cs.sjtu 2011.9程序设计 - 80void create( void ) cout nCREATE FUNCTION: EXECUTION BEGINS endl; CreateAndDestroy fifth( 5); static CreateAndDestroy sixth( 6); CreateAndDestroy seventh( 7); cout nCREATE FUNCTION: EXECUTION ENDS endl;1 con1 conMAINMAIN2 con2 con3 con3 conCREATECREATEBEBE5 con5 con6
77、 con6 con7 con7 conCREATECREATEENEND D7 de7 de5 de5 deMAINMAINRERE4 con4 conMAINMAINENDEND4 de4 de2 de2 de6 de6 de3 de3 de1 de1 de吃居毁啦鉴沈搀衷勇夹锗倘相近氧墨期篱喻唾庇假蓬译玫旺屡饲喧污喝厩第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 81void create( void ); int main() create(); create(); return 0;CREATECREATEBEBE5 con5 con6 con
78、6 con7 con7 conCREATECREATEENDEND7 de7 de5 de5 deCREATECREATEBEBE5 con5 con7 con7 conCREATECREATEENDEND7 de7 de5 de5 de6 de6 de测试静态的局部变量烙皇虏墅赦闷粳欲姓觅吨什铡柱东劫拂贰湃季崎艰曰测察锈砧吼荧奶广幸第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 82第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构
79、v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 掘甘阵僚拱蹦乎晦崭用嫁嗜柿慈择柴株坤糙尾厩玛舔驱疡凝咽糕鸽呜巍旅第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 83const对象对象vconst对象的定义对象的定义 const MyClass obj(参数表);(参数表);vconst对象不能被赋值,只能初始化,而对象不能被赋值,只能初始化,而且一定要初始化,否则无法设置它的值。且一定要初始化,否则无法设置它的值。潮劳梅抢免尊敷天苇千僵庇沏押驯烂摘擞芦秘翰矛
80、晾目滁眼榔啊刁躁澜每第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 84如何保证数据成员不被修改如何保证数据成员不被修改v数据成员一般都由成员函数修改。当定数据成员一般都由成员函数修改。当定义了一个常量对象后,如何使用这个对义了一个常量对象后,如何使用这个对象?象?vC+规定:对规定:对const对象只能调用对象只能调用const成成员函数员函数卉炸钒睫绳习撒扯沸敷届钟翅孔蜂符税秧渴调杀灼闰糠厢酋蹿姿饲紫翔瞒第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 85const成员函数成员函数v任何不修改数据成员的函数都应
81、该声明为任何不修改数据成员的函数都应该声明为const类类型。如果在编写型。如果在编写const成员函数时,不慎修改了数成员函数时,不慎修改了数据成员,或者调用了其他非据成员,或者调用了其他非const成员函数,编译成员函数,编译器将指出错误,这无疑会提高程序的健壮性。器将指出错误,这无疑会提高程序的健壮性。 class A int x; public: A(int i) x=i; int getx() const return x; ;酗律不焰亢贡幸盏划涎椿雪纺迭邻凋苔乳葵沸疡硼眷十玛管柱幸茁贯雕昏第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 86c
82、lass A int x; public: A(int i) x=i; int getx() const; ; int A:getx() const return x; 必须加必须加的妈园锌只使牺膛听倪肯雨憨危绦峻畦烃觉菇嘱酸挥牺蜀织拒寇绵娘侩人第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 87class A int x;public:A(int i) x=i;int getx() const x =7; /错误,修改了数据成员错误,修改了数据成员x return x;脏塔诲鳖纬颂写匿奸抉诺声咖尼科员嫉乌验贴挟刊征泄蛾嫩伶遭辫鹊噶谅第10部分创建功能更
83、强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 88第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 灰顿留以踩逼形八焊内蛹椭姬譬断屯踏仪未鸦扎啤萄诱伟助秧隆献济奸孔第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 89常量成员常量成员vconst数据成员只在某个对象生存期
84、内是常量,而对数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。同一类的不同的对象其于整个类而言却是可变的。同一类的不同的对象其const数据成员的值可以不同。数据成员的值可以不同。v常量成员的声明常量成员的声明 在该成员声明前加上在该成员声明前加上const。如。如 class abc const int x; ;酥岁荣衰炼锁湾谊发浸砰甚乞炔蕴之泣籍血寨闽炮从害桃都疗摈针哥淄迭第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 90常量数据成员常量数据成员v不能在类声明中初始化不能在类声明中初始化const数据成员。数据成员。class A/
85、错误,企图在类声明中初始化错误,企图在类声明中初始化const数据数据成员成员const int SIZE = 200;int arraySIZE; /错误,未知的错误,未知的SIZE;涸胯厘诈巢嫩梗危钦屡贿贪掌袱也俘握街缎绳迁阜尤述俺度拌速训癣孽铬第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 91const数据成员的初始化vconst数据成员的初始化只能在类构造函数的初数据成员的初始化只能在类构造函数的初始化表中进行,不能在构造函数中对他赋值。始化表中进行,不能在构造函数中对他赋值。v例:例:class AA(int size);/构造函数构造函数c
86、onst int SIZE;A:A(int size) : SIZE(size)/构造函数的初始化表构造函数的初始化表A a(100);/对象对象a的的SIZE的值为的值为100A b(200);/对象对象b的的SIZE的值为的值为200坝裔顺药晕写峦恍探班辫帧义往僳锣铱沽讫割涧脑治睹湛坏佑腋丘喧馒阑第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 92第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成
87、员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 碍江锅真吵军骨财敲奥焦暇曼武豆酒实彭担怠空滇肤鞍先京豫昼剑使兜穷第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 93静态成员v假设类假设类SavingAccount专门用于存放存款帐户,它包专门用于存放存款帐户,它包括存户的姓名、地址、存款额、利率等成员变量:括存户的姓名、地址、存款额、利率等成员变量:class SavingAccountchar m_name20; /存户姓名存户姓名 char m_addr60; /存户地址存户地址 dou
88、ble m_total; /存款额存款额double m_rate; /利率利率 ; 这家银行采用浮动利率,每个帐户的利息根据当天的挂牌利率这家银行采用浮动利率,每个帐户的利息根据当天的挂牌利率计算。这时计算。这时m_rate就不适合成为每个帐号一个资料,否则每天就不适合成为每个帐号一个资料,否则每天一开市,光把修改所有帐户的一开市,光把修改所有帐户的m_rate的值,就花掉不少时间。的值,就花掉不少时间。m_rate应该独立于各对象之外,成为整个类个对象共享的资料。应该独立于各对象之外,成为整个类个对象共享的资料。漾迹臃赫哈祖氮抵仲枣踊泌宏陋津寻纸叶屈徽俄痒脖雀垣徽伙赵免惟伟该第10部分创建
89、功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 94静态成员变量的声明v解决方法:在解决方法:在m_rate前面加上前面加上staticclass SavingAccountchar m_name20;/存户姓名存户姓名char m_addr60;/存户地址存户地址double m_total;/存款额存款额 static double m_rate; /利率利率鹅酗辊座济千琳浓抖贩腔迎窘误赋晓任喂筷啊醇锅候戴多杂贮象者蛮氮犀第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 95静态成员变量v静态成员变量不属于对象的一部分,而是静
90、态成员变量不属于对象的一部分,而是类的一部分;类的一部分;v静态成员变量的初始化不能放在类的构造静态成员变量的初始化不能放在类的构造函数中;函数中;v类定义并不分配空间,空间是在定义对象类定义并不分配空间,空间是在定义对象时分配时分配v但静态数据成员属于类,因此定义对象时但静态数据成员属于类,因此定义对象时并不为静态成员分配空间。并不为静态成员分配空间。曝满虾膛赋醇柄酉凤逃汗避唆姐姬尧默具辣掉钟奸蚁妖淆尉糠医祁辊政朝第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 96静态成员变量的定义静态成员变量的定义v为静态成员分配空间称为静态成员的定义为静态成员分配
91、空间称为静态成员的定义v静态成员的定义一般出现在类的实现文件中。静态成员的定义一般出现在类的实现文件中。如在如在SavingAccount类的实现文件中,必须要类的实现文件中,必须要如下的定义:如下的定义: double SavingAccount:rate = 0.05; 该定义为该定义为rate分配了空间,并给它赋了一个初分配了空间,并给它赋了一个初值值0.05。v如果没有这个定义,连接器会报告一个错误。如果没有这个定义,连接器会报告一个错误。 姜霄堑场孙棋崭洗甭钥加珊骇醋辗拯炉凌贴雷隅日尸揪堡易崇央滦裳囱程第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计
92、 - 97静态变量的使用静态变量的使用v可以通过作用域操作符从类直接调用。如:可以通过作用域操作符从类直接调用。如: SavingAccount:rate v但从每个对象的角度来看,它似乎又是对但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。象的一部分,因此又可以从对象引用它。如有个如有个SavingAccount类的对象类的对象obj,则可,则可以用:以用:obj.ratev由于是整个类共享的,因此不管用哪种调由于是整个类共享的,因此不管用哪种调用方式,得到的值都是相同的用方式,得到的值都是相同的 迂浑校毛至琳炸钳屉鹏棵逾驾淮剪履石狮颜茫沛慑技夷晕芯妆惭俗帽图效第10
93、部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 98静态成员函数v成员函数也可以是静态的。静态的成员函数是为成员函数也可以是静态的。静态的成员函数是为类的全体对象服务,而不是为某个类的特殊对象类的全体对象服务,而不是为某个类的特殊对象服务服务v由于静态成员函数不需要借助任何对象就可以被由于静态成员函数不需要借助任何对象就可以被调用,所以编译器不会为它暗加一个调用,所以编译器不会为它暗加一个this指针。因指针。因此,静态成员函数无法处理类中的非静态成员变此,静态成员函数无法处理类中的非静态成员变量。量。v静态成员函数的声明只需要在类定义中的函数原静态成员函数的
94、声明只需要在类定义中的函数原型前加上保留词型前加上保留词static。 鹰娱姥集枷捷桶竣西活朝课朝抗步几罩押开峙份拔焉弦吠理坐租是烁单楚第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 99静态成员函数的用途静态成员函数的用途v定义静态成员函数的主要目的是访问静定义静态成员函数的主要目的是访问静态的数据成员。态的数据成员。v如在如在SavingAccount类中,当利率发生变类中,当利率发生变化时,必须修改这个静态数据成员的值。化时,必须修改这个静态数据成员的值。为此可以设置一个静态的成员函数为此可以设置一个静态的成员函数 static void SetR
95、ate(double newRate) rate = newRate; 珐贪极冗睁墒钓赊抉藏酉胡乾三冷涵泞荤疼辅益舀皆晴韦雍中淬宴浅密憾第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 100静态成员函数使用说明v静态成员函数可定义为内嵌的,也可在类外定静态成员函数可定义为内嵌的,也可在类外定义。在类外定义时,不用义。在类外定义时,不用static。v静态成员函数的访问:可以通过类作用域限定静态成员函数的访问:可以通过类作用域限定符或通过对象访问符或通过对象访问 类名类名:静态成员函数名()静态成员函数名() 对象名对象名.静态成员函数名()静态成员函数名
96、()裳迎若甄升童缺龋膨改妖钉宰渣雹嵌幂令侍呆喘升嚣尺嫡售荔窟攫袱助誊第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 101静态成员函数实例1class goods int weight; static int total_weight; public: goods(int w); goods(); int weight(); static int totalweight();int goods:total_weight = 0;goods:goods(int w)weight=w; total_weight+=w;goods:goods()total_w
97、eight-=weight;int goods:weight()return weight;int totalweight()return total_weight;啃数碗晶屠烩颈蝴酶淹禁汹洪庙龚辕俐呛华粤焚莹柔急歉配锤簧甩望颊堰第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 102静态成员函数实例静态成员函数实例2v在程序执行的某个时刻,有时需要知道某个类在程序执行的某个时刻,有时需要知道某个类已创建的对象个数,现在仍存活的对象个数。已创建的对象个数,现在仍存活的对象个数。 v类设计:类设计:数据成员:为了实现这个功能,我们可以在类中定数据成员:为了实
98、现这个功能,我们可以在类中定义两个静态的数据成员:义两个静态的数据成员:obj_count和和obj_living。成员函数:要实现计数功能,我们可以在创建一个成员函数:要实现计数功能,我们可以在创建一个对象时,对这两个数各加对象时,对这两个数各加1。当撤销一个对象时,。当撤销一个对象时,obj_living减减1。为了知道某一时刻对象个数的信息,。为了知道某一时刻对象个数的信息,可以定义一个静态的成员函数返回这两个值。可以定义一个静态的成员函数返回这两个值。 连幻渠伺较绘虫爸陆过挪悲睡频葵避系释盔亲漂扣终钧舶芒硷捣抄噬撂懊第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011
99、.9程序设计 - 103类定义类定义#ifndef _StaticSample_h#define _StaticSample_h#include using namespace std;class StaticSample private:static int obj_count;static int obj_living;public:StaticSample() +obj_count; +obj_living;StaticSample() -obj_living;static void display() /静态成员函数静态成员函数 cout 总对象数:总对象数: obj_count t存
100、活对象数:存活对象数: obj_living display(); /通过指向对象的指针调用静态成员函数通过指向对象的指针调用静态成员函数 delete p2; StaticSample:display(); return 0;木龟候啪娃敢梯牧奏间帕新淬子痛京书丢霓括捉草悄外娜松侵隘捏收育怯第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 105执行结果执行结果总对象数:总对象数:0 存活对象数:存活对象数:0总对象数:总对象数:2 存活对象数:存活对象数:2总对象数:总对象数:4 存活对象数:存活对象数:4总对象数:总对象数:4 存活对象数:存活对象数:
101、3总对象数:总对象数:4 存活对象数:存活对象数:2画淫萌芽级投化襄缀步涅茅巍禽嘴服鸵臼碾俯敲疵殃勇带琴栈袄砷吠胁教第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 106静态的常量成员静态的常量成员v静态的常量成员:整个类的所有对象的共静态的常量成员:整个类的所有对象的共享常量享常量v静态的常量成员的声明:静态的常量成员的声明:static const 类型类型 数据成员名数据成员名 = 常量表达式;常量表达式; v注意注意const数据成员和数据成员和static const数据成员数据成员的区别。的区别。 辨苗侠覆雏摊协糊捣钮贺菜膜乡孺呵边绩画崎膛柠
102、企难牟截苫匪圣圭盘橇第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 107静态常量成员实例静态常量成员实例v例如,需要在某个类中需要用到一个数例如,需要在某个类中需要用到一个数组,而该数组的大小对所有对象都是相组,而该数组的大小对所有对象都是相同的,则在类中可指定一个数组规模,同的,则在类中可指定一个数组规模,并创建一个该规模的数组。如下所示:并创建一个该规模的数组。如下所示: class sample static const int SIZE = 10; int storageSIZE; ;私疮胁烃书襟勃榆呕谷酷捂买婪宇构斜汉温叹寐则志恐囤父赴症拍所
103、瓮答第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 108老版本的兼容老版本的兼容v某些旧版本的某些旧版本的C+不支持静态常量不支持静态常量v解决方法:用不带实例的枚举类型解决方法:用不带实例的枚举类型v如:如:class sample enum SIZE = 10; int storageSIZE; ;脓掺掩颖区栅析习灭埠赛陛父兔疏脾恭剪瓜驼庭嘶棍冠且瞒里怪叭首倚捻第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 109第第10章章 创建功能更强的类型创建功能更强的类型v从面向过程到面向对象从面向过程到面向对象 v
104、类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 亏镶酋轧囱耪昏澜碍萎卉热戌翌挟硕篷越翟便峭萧烩汗茁擎吐溺寄语豹洱第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 110友元v类的私有成员只能通过它的成员函数来类的私有成员只能通过它的成员函数来访问。访问。v友元函数是一扇通往私有成员的后门。友元函数是一扇通往私有成员的后门。v友元可以是一个一般函数(友元函数),友元可以是一个一般函数(友
105、元函数),也可以是另一个类的成员函数(友元成也可以是另一个类的成员函数(友元成员),还可以是整个类(友元类)。员),还可以是整个类(友元类)。薪笆椰端揣蓬唁喘觅兴弃貌桨卒什氏柬昌祟荔脯蛇锈载圭旧讳莉酗斥登削第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 111友元特点友元特点v友元关系是授予的而不是索取的。也就是说,如果友元关系是授予的而不是索取的。也就是说,如果函数函数 f 要成为类要成为类A的友元,类的友元,类A必须显式声明函数必须显式声明函数f是他的友元,而不是函数是他的友元,而不是函数f自称是类自称是类A的友元。的友元。v友元关系不是对称关系,如
106、果类友元关系不是对称关系,如果类A声明了类声明了类B是它是它的友元,并不意味着类的友元,并不意味着类A也是类也是类B的友元。的友元。v友元关系不是传递关系。如果类友元关系不是传递关系。如果类A是类是类B的友元,的友元,类类B是类是类C的友元,并不意味着类的友元,并不意味着类A是类是类C的友元。的友元。 骏模虱罗幅顾硷据浩镍逊缸来佛豌挽戒鸿敷斋烩估名劈滤伶玉嘲样人仲晕第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 112友元函数的声明v用关键词用关键词friend说明友元函数说明友元函数v说明位置:可以定义在类外部,也可定说明位置:可以定义在类外部,也可定
107、义在类内部。可声明在义在类内部。可声明在public部分,也部分,也可声明在可声明在private部分。部分。肥蹿期履缕森棒呈蚀炕骸晕瑟辗合垛乡单养礼爪幌根儿驯乡篙覆跑痔识贷第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 113友元函数的声明实例v定义在类内定义在类内#include #include class girl char name10; int age; public:girl(char *n, int d) strcpy(name,n); age=d; friend void disp(girl &x) /定义定义 coutx.name“
108、“ x.ageendl;main() girl e(abc, 15); disp(e); l定义在类外定义在类外#include #include class girl char name10; int age; public:girl(char *n, int d) strcpy(name,n); age=d; friend void disp(girl &x); ; void disp(girl &x)/定义定义 coutx.name “ x.ageendl; main() girl e(abc, 15); disp(e); 一般必须有参数一般必须有参数锅靖挺清杏淮颓横政括糖铆批牡著疯湛杭
109、泅逢铅锗健芦净尼肖猴碌天拍悟第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 114友元成员v是其他某个类的成员函数是其他某个类的成员函数v可以访问可以访问friend声明语句所在类的私有成员和声明语句所在类的私有成员和公有成员的成员函数公有成员的成员函数v类类A的成员函数作为类的成员函数作为类B的友元函数时,必须的友元函数时,必须先定义类先定义类A,再定义类,再定义类B。在定义类。在定义类A和和B前必前必须先声明类须先声明类B。v格式:格式: friend friend 函数返回类型函数返回类型 类名标识符类名标识符:函数名函数名( (参数列表参数列表)
110、 ); 居呵饵长馅妮蚂弦闷亦老睁踩衙菲勾户柬桅制废哟袍巨敛籍莫埋橇芥靛哑第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 115友元成员实例class boy; /类的声明类的声明class girl char name10; int age; public:girl(char *n, int d) strcpy(name,n); age=d;void disp(boy &x);class boy char name10; int age; public:boy(char *n, int d) strcpy(name,n);age=d; friend vo
111、id girl:disp(boy &);void girl:disp(boy &x) coutname ageendl; coutx.name x.ageendl;void main() girl e(abc, 15); boy b(cde,20); e.disp(b); abc 15cde 20窘九谬紊撂明儒可脖铡唱瞬忍盖檀核饰讯狐匪荔帅扔跪嘱他巷脊劝巍温潭第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 116友元类v整个类作为另一个类的友元。整个类作为另一个类的友元。v当当A类被说明为类类被说明为类B的友元时,类的友元时,类A的所的所有函数都是类有函
112、数都是类B的友元函数的友元函数v声明方法:声明方法: class Y.; class X . friend Y;/或或friend class Y ;袱含赢锭拔谴磊迁噶岭募薯蹲泉赴甩短易含组哇志公摇氢先曾迢克志脓绎第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 117友元类实例class boy;class girl char name10; int age; public:girl(char *n, int d) strcpy(name,n); age=d;void disp(boy &x);class boy char name10; int age
113、; public:boy(char *n, int d) strcpy(name,n);age=d; friend class girl;void girl:disp(boy &x) coutname ageendl;coutx.name x.ageendl; void main() girl e(abc, 15); boy b(cde,20); e.disp(b); abc 15cde 20幸铲汀些拒蝉搅痞藤男竟抖晰割哆秽铜匿谗贺逾埠禹疲吁萨琶掠匡冯旋浙第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 118友元声明说明友元声明说明v友元关系可以写在类定
114、义中的任何地方友元关系可以写在类定义中的任何地方v但一个较好的程序设计的习惯是将所有但一个较好的程序设计的习惯是将所有的友元关系的声明放在最前面的位置,的友元关系的声明放在最前面的位置,并且不要在他的前面添加任何访问控制并且不要在他的前面添加任何访问控制说明说明久洞疡半进揉阁靳勘蘸猜的墅蕉吞硝瘟孕拭罚屿芹完叫酶累边伞归朋拈搀第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 119class girl friend void disp(girl &x); private: char name10; int age; public: girl(char *n,
115、 int d) strcpy(name,n); age=d; ;void disp(girl &x)/友元函数的定义友元函数的定义 coutx.name x.ageendl; int main() girl e(abc, 15); disp(e); return 0; 靛玉逐孩昨竟涡婶绅拖舶耀眺呼呀默豌芒油戚峙涩慌规递哼敝旋谊叮悄丰第10部分创建功能更强的类型程序设计程序设计 cs.sjtu 2011.9程序设计 - 120总结总结 v本章介绍了面向对象的程序设计的基本本章介绍了面向对象的程序设计的基本思想。面向对象程序设计的基本思想是思想。面向对象程序设计的基本思想是如何根据应用的需求创造合适的类型,如何根据应用的需求创造合适的类型,用该类型的对象来解决特定的问题。用该类型的对象来解决特定的问题。v本章主要介绍了如何定义一个类,如何本章主要介绍了如何定义一个类,如何通过访问控制实现信息的封装。如何定通过访问控制实现信息的封装。如何定义类的对象,如何实现对象的初始化,义类的对象,如何实现对象的初始化,如何操作对象。如何操作对象。 栏摩摆隘华倪腻芯艘伪柴潮有氮家藏跟踏冶桃瑟绝帛庐诛渐散稍读堆迈验第10部分创建功能更强的类型程序设计