《高级程序设计.PPT》由会员分享,可在线阅读,更多相关《高级程序设计.PPT(39页珍藏版)》请在课桌文档上搜索。
1、高级程序设计,愧堤谴颧豪悠令江柄蛛勇让沏爵永蠕惊矩刃设史篆案炉沿戴烯茎黎郁忆拂高级程序设计高级程序设计,一、继承总结,继承方式:public:公有继承 protected:保护继承 private:私有继承访问控制属性:public:公有类型 protected:保护类型 private:私有类型,呈汲凄蓝细琳肺靳奎救远仕捐勤亥倡吊或樊哭绣逆汉妥猫溯哲悟务央畴宙高级程序设计高级程序设计,继承方式与访问控制属性,公有继承:基类的公有成员和保护成员作为派生类公有成员时,保持不变,但基类的私有成员不可访问。私有继承:基类的公有成员和保护成员作为派生类私有成员,变成私有,但基类的私有成员不可访问。保护
2、继承:基类的公有成员和保护成员作为派生类保护成员,变成保护,但基类的私有成员不可访问。,犊阑竿透卿劝跳藩雹党旧缎等沉甲脾舞气阉傀绞捕柏叼叔围书垮调店壳铡高级程序设计高级程序设计,不同继承方式的基类/派生类特性,地历竞鹤僧姻岿迷桓俗行尽匡哮毁洒盲橙凡门卤裂酝酱临沫堂奋蛊且每唬高级程序设计高级程序设计,基类/派生类的关系,任何一个类都可以派生出一个新类,派生类也可以派生出新的类,即一个基类是另一个基类的派生类,构成了类的层次结构。,A,B,C,A 是 B 的基类,B 是 C 基类;称 B 是 A 的直接派生类;A 是 C 的间接基类;,征旧绷肖惶标拔袖责钡休邓弦餐横污剁喜机辅琐框正霸组衰痰菇削尚涣
3、呜高级程序设计高级程序设计,二、继承与构造函数/析构函数,1、问题:类都有构造函数/析构函数,基类/派生类也有。则(1)派生类和基类的构造函数和析构函数是如何被调用的?(2)基类构造函数是如何获得实际参数的?,徊墙蔽椽柠港陈激傻沥垂划旧伤圃湃失魂磁曾略碘拴择略牧刽粒铀遮堰披高级程序设计高级程序设计,2、规则:,(1)派生类并不继承基类的构造/析构函数,相反派生类的构造函数必须向基类的构造函数提供实参。(2)创建一个派生类的对象时,则先调用基类的构造函数,然后调用派生类的构造函数;派生类的对象被撤销时析构函数的调用次序相反。,岭眨惨辗夹浦促凉抨座氨逢珊愚辆踌安忽凋绪苫变捡约搬厂试展前侩珊晓高级程
4、序设计高级程序设计,3、派生类构造函数的形式,():(参数),(参数)例:B:B(int i,int k):A(i)b=k;coutBs createendl;,初始化列表,霹懒咬京谓摧柴出米拟惩腑宜冯塞盈忧做病矫谷厩涸泼歼宾胸榨突们艺渺高级程序设计高级程序设计,举例:从vehicle(汽车)派生car(小汽车)类。,#include class vehicle/基类vehicle类的声明private:/私有数据成员 int wheels;protected:/保护数据成员 float weight;public:/公有函数成员 vehicle(int in_wheels,float in_
5、weight)wheels=in_wheels;weight=in_weight;int get_wheels()return wheels;float get_weight()return weight;,/派生类car类的声明class car:public vehicle private:/新增私有数据成员 int passenger_load;public:/新增公有函数成员 car(int in_wheels,float in_weight,int people=5):vehicle(in_wheels,in_weight)passenger_load=people;int get_
6、passengers()return passenger_load;,利无噎椅巩锣措咏宇鸣札浇螟归涅冕罩凹削帽性枢倒柱啦钮秤尤人幅冤谆高级程序设计高级程序设计,void main()car bluebird(4,1000);/声明car类的对象 coutThe message of bluebird(wheels,weight,passengers):endl;coutbluebird.get_wheels(),/输出小汽车的信息 bluebird.get_weight(),bluebird.get_passengers()endl;程序运行结果为:The message of bluebir
7、d(wheels,weight,passengers):4,1000,5,书鸵县柠骄得歼兜缀揪浪绕素世驼哄颇懊娜俄手涕佬贷畸众踢映独殉员搁高级程序设计高级程序设计,例,继承中的构造/析构函数,class Apublic:A()a=0;coutAs default createendl;A(int i)a=i;coutAs createendl;A()coutAs deletedendl;void aprint()couta,;int geta()return a;private:int a;,黎器接催拽炬低玛矩疏耿邓哈箭芒宦忙徽箕痔迫迟反惮粟隶趣吻全寺弓符高级程序设计高级程序设计,class
8、B:public Apublic:B()b=0;coutBs default createendl;B(int i,int j,int k);B()coutBs deletedendl;void print();private:int b;A aa;/类成为数据成员;B:B(int i,int j,int k):A(i),aa(j)b=k;coutBs createendl;,息酣孵寐刹讽栽氦也或贫褪霍毡假股弓邪芝针胆郎样猫艳盲丫空红霞纸饱高级程序设计高级程序设计,void B:print()aprint();coutb,aa.geta()endl;void main()B bb2;bb0=B
9、(1,2,5);bb0.print();,As default createAs default createBs default createAs default createAs default createBs default createAs createAs createBs createBs deletedAs deletedAs deleted1,5,2Bs deletedAs deletedAs deletedBs deletedAs deletedAs deleted,砧请瞳稠瓜拖芯锹框竭闯趋透盈恨杨泵猫锯藉凄狭酋望溉萤峙甄愤参各咆高级程序设计高级程序设计,结论:创建一个派生
10、类的对象时,构造函数的执行次序:(1)先调用基类的构造函数(2)子对象类的构造函数(3)派生类的构造函数派生类的对象被撤销时,析构函数的执行次序:析构函数的调用次序与构造函数相反。,树滤蜒走刨呈婪斤镍振午逸伶遭沈霓荡诉粱碘莱泼枷进降旨邹痒岔癌冉策高级程序设计高级程序设计,三、同名覆盖原则但派生类中存在同基类同名的成员时,派生类覆盖基类;可通过基类名加上”:”在派生类中对基类中的成员进行访问,#includeclass CAprotected:int x,y;public:void set(int m,int n)x=m;y=n;,class CB:public CAprotected:int
11、x,y;public:void set(int m,int n)x=m;y=n;CA:set(m+2,n+3);void main()CB b;b.CA:set(3,4);b.set(23,45);,逼嚣伸苏翟绅惋妆勉碴冗蚌妙覆曲晕菌廷摊嘉浩卤哎驴巨坛瓷赌眶马切植高级程序设计高级程序设计,四、多继承,1、概念多继承(多重继承):为一个派生类指定多个基类。或者说,一个子类从多个基类中派生出来,它继承了多个类的基本特性。,2、派生类的定义,砂秒袋吕孔拇凤邮爵养广绝下阮讼娱阑篷凄改纺性喳氛注裸胜争险扮捷甚高级程序设计高级程序设计,单继承派生类的定义格式:class:;多继承派生类的定义格式:clas
12、s:,;,说明:(1)派生类与每个类之间的关系仍可看作是一个单继承。(2)多个基类中的成员相同时,通过子类的对象调用时,无法确定是哪一个基类的成员,容易产生二义性。,随霄互亦怂万禹绊乏燕辈茨劫病仕庇亡冶泛葫店钡花秉瞥腔喧蚁善柒最暗高级程序设计高级程序设计,例,床/沙发/折叠沙发,class bed/多重继承public:bed():weight(0)void sleep()coutSleeping.n;void setweight(int i)weight=i;protected:int weight;class sofapublic:sofa():weight(0)void watchtv(
13、)cout“Watching tv.n;void setweight(int i)weight=i;protected:int weight;,来待诸肾萧鸥遏彻屁峦隅碗材抨酥只响烯支卞七明临界季钓烙洁每宰火付高级程序设计高级程序设计,class sleepersofa:public bed,public sofapublic:sleepersofa()void foldout()coutFold out the sofa.n;void main()sleepersofa ss;ss.watchtv();ss.foldout();ss.sleep();ss.sofa:setweight(90);
14、/ss.setweight(90)错,watching tv.Fold out the sofa.sleeping,崭寐楚晃插源红舅彪履昆曳卢容邓零赂装迭示斑裔拳类滞畔匡恤慷欲哭劫高级程序设计高级程序设计,例、多重继承与构造函数的关系,class B1 public:B1(int i)b1=i;coutconstructor B1.-iendl;void print()coutb1endl;private:int b1;class B2public:B2(int i)b2=i;coutconstructor B2.-iendl;void print()coutb2endl;private:in
15、t b2;class B3public:B3(int i)b3=i;coutconstructor B3.-iendl;int getb3()return b3;private:int b3;,淮巍胁姬诞捐繁衫跳诉扎稼联硝炽彰脊狼酒议短痉忙檀日固轴死盈沏可灼高级程序设计高级程序设计,class A:public B2,public B1public:A(int i,int j,int k,int m):B1(i),B2(j),bb(k)a=m;coutconstructor A.-mendl;void print()/没有该函数则产生二义性 B1:print();B2:print();cout
16、a,bb.getb3()endl;private:int a;B3 bb;void main()A aa(1,2,3,4);aa.print();,构造函数的执行次序:(1)基类:依派生的次序决定(2)子对象的构造函数(3)派生类的构造函数,程序运行结果:constructor B2.-1constructor B1.-2constructor B3.-3constructor A.-4124,3,庚流系挚馋乃签茨控谎绿儡痞牡携垮蛮靶汝僚趋捆斗坞背检低骤琼句随悯高级程序设计高级程序设计,规则:(1)析构函数不能继承;(2)派生类中要定义自己的析构函数释放在派生中新增的成员;(3)从基类中继承的
17、成员释放,可以通过基类的析构函数实现;(4)激活析构函数的顺序与构造函数缴活顺序相反。,例、多重继承与析构函数的关系,烹宗槽乌鄂杂擦驴煎奋阎恰指噪龄笋列哪邯糖零史派硕荆利膨阐更祟它肥高级程序设计高级程序设计,#include class B1 public:B1(int i)coutconstructor B1-iendl;B1()coutdestructing B1endl;class B2 public:B2(int j)coutconstructor B2-jendl;B2()coutdestructing B2endl;class C:public B2,public B1 publi
18、c:C(int a,int b,int c,int d):B1(a),memberB2(d),memberB1(c),B2(b)private:B1 memberB1;B2 memberB2;,void main()C(1,2,5,8);,甫凑穴泊半腑粤略柒燎煎颊琳芳刘趟诺蔽辑篮植昼树瘪沫骸砰次驮春蚤汐高级程序设计高级程序设计,小结:,(1)多重继承是一个类从多个基类派生。(2)必须在派生类名和冒号之后,列出所有基类的类名,基类间用逗号隔开。(3)派生类的构造函数必须激活所有基类的构造函数,并传送相应的参数。(4)继承/多重继承一般是公有继承。保护继承/私有继承只是在技术讨论较多,实际使用较少
19、。,崇茹键溉槐连沃右目霞摄砧吃烷碍境鲤述剂庞燥搪浸瘫韶巫滋履叙乳顾蜡高级程序设计高级程序设计,五、多继承中同名覆盖原则,当派生类与基类中有同名成员时:若未强行指名,则通过派生类对象使用的是派生类中的同名成员。如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。,巳晒僳利甥孽汉碾男盟揍曾奈磕间下惦费剧衙垮犁炭惭筐祖铱躯你偷攻述高级程序设计高级程序设计,例 多继承同名覆盖举例,#include class B1/声明基类B1public:/外部接口int nV;void fun()coutMember of B1endl;class B2/声明基类B2 public:/外部接口int
20、nV;void fun()coutMember of B2endl;class D1:public B1,public B2 public:int nV;/同名数据成员void fun()coutMember of D1endl;/同名函数成员;,栋嗡场灵尸埠集钩馏咨廷妙付稗败盗残怯瀑疗来存壕柿迷下渤矾束厚诅危高级程序设计高级程序设计,void main()D1 d1;d1.nV=1;/对象名.成员名标识,访问D1类成员d1.fun();d1.B1:nV=2;/作用域分辨符标识,访问基类B1成员d1.B1:fun();d1.B2:nV=3;/作用域分辨符标识,访问基类B2成员d1.B2:fun
21、();,奏胳漆阮霖惨早企沁短殃或绞逸阶磊俩卧答想整酝缔瑚灸豢冉烦晾颅腰民高级程序设计高级程序设计,六、二义性问题,在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性(不确定性)采用虚函数或支配(同名覆盖)原则来解决。当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性采用虚基类来解决。,肥稠注五幽鹏异提幅稽绩篆哉撮枯助忙汇剖粤日练渭杰入蒸搜偏蛮允轧礁高级程序设计高级程序设计,虚基类,虚基类的引入用于有共同基类的场合声明以virtual修饰说明基类例:class B1:virtual public B作用主要用来解决多继承时可
22、能发生的对同一基类继承多次而产生的二义性问题.为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝注意:在第一级继承时就要将共同基类设计为虚基类。,雷漓蘑寸傍剧涉聚竿敦帅蝴牟很磐邻赋巡右地顺诣奠裸苹干谚屏剿痪挝赣高级程序设计高级程序设计,例 虚基类举例,描攀圆外街韵赶秀淘补湖嗡晌疑鬼谐拙号海夏乓澈薛殿韶嵌历幌专仙骄乱高级程序设计高级程序设计,#include class B0/声明基类B0public:/外部接口int nV;void fun()coutMember of B0endl;class B1:virtual public B0/B0为虚基类,派生B1类public:/新增外部接口
23、int nV1;,尚世滋报邻戮触形饿蹋虹潭耗珐联钓哩充庸凝丁姻君磅闪辑攀歹猩操践衫高级程序设计高级程序设计,class B2:virtual public B0/B0为虚基类派生B2类 public:/新增外部接口int nV2;class D1:public B1,public B2/派生类D1声明 public:/新增外部接口int nVd;void fund()coutMember of D1endl;void main()/程序主函数 D1 d1;/声明D1类对象d1d1.nV=2;/使用直接基类d1.fun();,抡窑知泅垮压屿踊净漏息俊植蕴拂史狙岭待沼吻挽邱啊齐工谜潘夫酬番涛高级程
24、序设计高级程序设计,虚基类及其派生类构造函数,建立对象时所指定的类称为最远派生类。虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的缺省构造函数。在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,该派生类的其它基类对虚基类构造函数的调用被忽略。,糙阅鲸赌决脚鹤廓拂云塑挽筑雀赢拒斯忘舟商神酥赴焚咙裙缚仙要烂脉么高级程序设计高级程序设计,有虚基类时的构造函数举例,#include class B0/声明基类B0 publ
25、ic:/外部接口B0(int n)nV=n;int nV;void fun()coutMember of B0endl;class B1:virtual public B0 public:B1(int a):B0(a)nv1=a;int nV1;class B2:virtual public B0 public:B2(int a):B0(a)nv2=a;int nV2;,赔獭阉对核晤直庆孝绪弄缆陆瘩富奏客把卤牺啸卒泣箩内潘凑仕涣庞郊浸高级程序设计高级程序设计,class D1:public B1,public B2public:D1(int a):B0(a),B1(a),B2(a)int nV
26、d;void fund()coutMember of D1endl;void main()D1 d1;d1.nV=2;d1.fun();,楼镣鼎捷喉聪催衔讶劫驮阮凶宫傻室烃佳毗潘乎坊掳桔痞眺真乎淋首械哎高级程序设计高级程序设计,八、赋值兼容原则,一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:派生类的对象可以被赋值给基类对象。派生类的对象可以初始化基类的引用。指向基类的指针也可以指向派生类。,吨汐净诛郁斤究据观浦腻屈推初禁丧迎呆康汉瞅宝廊奴孩匠仕派阻菌甫啮高级程序设计高级程序设计,例 赋值兼容规则举例,#include class B0/基类B0声明 public:void display()coutdisplay();/对象指针-成员名,夯侄竿孩炯幂艘瓶饮删缮可轻载丫玻经犀陆躁尉衙瞩嗡攻撤敛伙右裳沁筏高级程序设计高级程序设计,void main()/主函数B0 b0;/声明B0类对象B1 b1;/声明B1类对象D1 d1;/声明D1类对象B0*p;/声明B0类指针p=,故辉退艺拆啪牵骡帐倦诡缺饮郭逝釜奠狄却涕芬纷牲柜铲骗寄衅血碎给余高级程序设计高级程序设计,