版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、高级程序设计高级程序设计主主 讲:李晓勇讲:李晓勇:lxyonghn163Telphone:19194055一、承继总结一、承继总结 承继方式:承继方式: public : 公有承继公有承继 protected : 维护承继维护承继 private : 私有承继私有承继访问控制属性:访问控制属性: public : 公有类型公有类型 protected : 维护类型维护类型 private : 私有类型私有类型承继方式与访问控制属性承继方式与访问控制属性不同承继方式的基类不同承继方式的基类/派生类特性派生类特性基类成员访问控制基类成员访问控制继承访问控制继承访问控制在派生类中的访问控制在派生类
2、中的访问控制publicpublicpublicprotectedprotectedprivate不可访问不可访问publicprotectedprotectedprotectedprotectedprivate不可访问不可访问publicprivateprivateprotectedprivateprivate不可访问不可访问基类基类/派生类的关系派生类的关系 任何一个类都可以派生出一个新类,派生类也可以派生出新任何一个类都可以派生出一个新类,派生类也可以派生出新的类,即一个基类是另一个基类的派生类,构成了类的层次构造。的类,即一个基类是另一个基类的派生类,构成了类的层次构造。ABCA 是是
3、 B 的基类,的基类, B 是是 C 基类;基类;称称 B 是是 A 的直接派生类;的直接派生类;A 是是 C 的间接基类;的间接基类;二二 、承继与构造函数、承继与构造函数/析构函数析构函数1、问题:、问题: 类都有构造函数类都有构造函数/析构函数,基类析构函数,基类/派生类也有。派生类也有。那么那么1)派生类和基类的构造函数和析构函数是如何被调用的?派生类和基类的构造函数和析构函数是如何被调用的?2)基类构造函数是如何获得实践参数的?基类构造函数是如何获得实践参数的?2、规那么:、规那么:1)派生类并不承继基类的构造派生类并不承继基类的构造/析构函数,相反派生类的构造函数必析构函数,相反派
4、生类的构造函数必需向基类的构造函数提供实参。需向基类的构造函数提供实参。2)创建一个派生类的对象时,那么先调用基类的构造函数,然后调用创建一个派生类的对象时,那么先调用基类的构造函数,然后调用派生类的构造函数;派生类的对象被撤销时析构函数的调用次序相派生类的构造函数;派生类的对象被撤销时析构函数的调用次序相反。反。3、派生类构造函数的方式、派生类构造函数的方式): 参数参数),参数参数) 例:例:B:B(int i ,int k):A(i)b=k;coutBs createendl;初始化列表初始化列表举例:从举例:从vehicle(汽车汽车)派生派生car(小汽车小汽车)类。类。#inclu
5、de class vehicle/基类基类vehicle类的声明类的声明private: /私有数据成员私有数据成员 int wheels; protected: /维护数据成员维护数据成员 float weight;public公有函数成员公有函数成员 vehicle(int in_wheels, float in_weight) wheels=in_wheels; weight=in_weight; int get_wheels() return wheels; float get_weight() return weight; ;/派生类派生类car类的声明类的声明class car:p
6、ublic 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_passengers() return passenger_load;void main() car bluebird(4,1000); /声明声明car类的对象类的对象 coutThe message of bl
7、uebird(wheels,weight,passengers):endl; coutbluebird.get_wheels(), /输出小汽车的信息输出小汽车的信息 bluebird.get_weight(), bluebird.get_passengers()endl;程序运转结果为:程序运转结果为:The message of bluebird(wheels,weight,passengers):4,1000,5例,承继中的构造例,承继中的构造/析构函数析构函数class Apublic:A() a=0; coutAs default createendl; A(int i) a=i;
8、coutAs createendl; A() coutAs deletedendl; void aprint() couta,; int geta() return a; private:int a;class 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;co
9、utBs createendl;void B:print() aprint(); coutb,aa.geta()endl;void main( )B bb2;bb0= B(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 deletedB
10、s deletedAs deletedAs deleted结论:结论:创建一个派生类的对象时,构造函数的执行次序:创建一个派生类的对象时,构造函数的执行次序:1)先调用基类的构造函数先调用基类的构造函数2)子对象类的构造函数子对象类的构造函数3)派生类的构造函数派生类的构造函数派生类的对象被撤销时,析构函数的执行次序:派生类的对象被撤销时,析构函数的执行次序:析构函数的调用次序与构造函数相反。析构函数的调用次序与构造函数相反。三、同名覆盖原那么三、同名覆盖原那么但派生类中存在同基类同名的成员时,派生类覆但派生类中存在同基类同名的成员时,派生类覆盖基类;可经过基类名加上盖基类;可经过基类名加上:
11、在派生类中对基类中在派生类中对基类中的成员进展访问的成员进展访问#includeclass CAprotected: int x,y;public: void set(int m, int n) x=m; y=n;class CB: public CAprotected: int 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、概念、概念多承继多重承继:为一个派生类指定多个基类。或者说,一多承继多重承继:为一个
12、派生类指定多个基类。或者说,一个子类从多个基类中派生出来,它承继了多个类的根本特性。个子类从多个基类中派生出来,它承继了多个类的根本特性。 2、派生类的定义、派生类的定义单承继派生类的定义格式:单承继派生类的定义格式:class :;多承继派生类的定义格式:多承继派生类的定义格式:class : , ;阐明:阐明:1派生类与每个类之间的关系仍可看作是一个单承继。派生类与每个类之间的关系仍可看作是一个单承继。2多个基类中的成员一样时,经过子类的对象调用时,无法确定多个基类中的成员一样时,经过子类的对象调用时,无法确定是哪一个基类的成员,容易产生二义性。是哪一个基类的成员,容易产生二义性。例,例,
13、 床床/沙发沙发/折叠沙发折叠沙发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( ) cout“Watching tv.n; void setweight(int i) weight=i; protected:int weight;class sleepersofa : public b
14、ed, public sofapublic:sleepersofa( ) void foldout( )coutFold out the sofa.n;void main( )sleepersofa ss;ss.watchtv( );ss.foldout ( );ss.sleep ( );ss.sofa:setweight (90); / ss.setweight (90)错错watching tv.Fold out the sofa.sleeping例、多重承继与构造函数的关系例、多重承继与构造函数的关系class B1 public: B1(int i) b1=i; coutconstru
15、ctor B1.-iendl; void print( ) coutb1endl; private: int b1;class B2public: B2(int i) b2=i; coutconstructor B2.-iendl; void print( ) coutb2endl; private:int 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,
16、int j, int k, int m):B1(i),B2(j),bb(k) a=m; coutconstructor A.-mendl; void print( ) /没没有有该该函函数数那那么产么产生二生二义义性性 B1:print ( ); B2:print ( ); couta,bb.getb3( )endl; private: int a; B3 bb;void main( )A aa(1,2,3,4);aa.print ( );构造函数的执行次序:构造函数的执行次序:1基类:依派生的次序决议基类:依派生的次序决议2子对象的构造函数子对象的构造函数3派生类的构造函数派生类的构造函数程
17、序运转结果:程序运转结果:constructor B2.-1constructor B1.-2constructor B3.-3constructor A.-4124,3规那么:规那么:1析构函数不能承继;析构函数不能承继;2派生类中要定义本人的析构函数释放在派生中新增的派生类中要定义本人的析构函数释放在派生中新增的成员;成员;3从基类中承继的成员释放,可以经过基类的析构函数从基类中承继的成员释放,可以经过基类的析构函数实现;实现;4激活析构函数的顺序与构造函数缴活顺序相反。激活析构函数的顺序与构造函数缴活顺序相反。例、多重承继与析构函数的关系例、多重承继与析构函数的关系#include cl
18、ass 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 public: C(int a, int b ,int c, int d ) :B1(a),memberB2(d),memberB1(c ),B2(b) private: B1 memberB1; B2 memberB2;
19、void main( ) C(1,2,5,8);小结:小结:1多重承继是一个类从多个基类派生。多重承继是一个类从多个基类派生。2必需在派生类名和冒号之后,列出一切基类的类必需在派生类名和冒号之后,列出一切基类的类名,基类间用逗号隔开。名,基类间用逗号隔开。3派生类的构造函数必需激活一切基类的构造函数,派生类的构造函数必需激活一切基类的构造函数,并传送相应的参数。并传送相应的参数。4承继承继/多重承继普通是公有承继。维护承继多重承继普通是公有承继。维护承继/私有私有承继只是在技术讨论较多,实践运用较少。承继只是在技术讨论较多,实践运用较少。五、多承继中同名覆盖原那么五、多承继中同名覆盖原那么当派
20、生类与基类中有同名成员时:当派生类与基类中有同名成员时:假设未强行指名,那么经过派生类对象运假设未强行指名,那么经过派生类对象运用的是派生类中的同名成员。用的是派生类中的同名成员。如要经过派生类对象访问基类中被覆盖的如要经过派生类对象访问基类中被覆盖的同名成员,应运用基类名限定。同名成员,应运用基类名限定。例例 多承继同名覆盖举例多承继同名覆盖举例#include class B1/声明基类声明基类B1public: /外部接口外部接口int nV;void fun coutMember of B1endl;class B2/声明基类声明基类B2 public:/外部接口外部接口int nV;
21、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.
22、B2:fun ;六、二义性问题六、二义性问题在多承继时,基类与派生类之间,或基类之间出现同名成员时,在多承继时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性不确定性将出现访问时的二义性不确定性采用虚函数或支配同名覆采用虚函数或支配同名覆盖原那么来处理。盖原那么来处理。当派生类从多个基类派生,而这些基类又从同一个基类派生,那当派生类从多个基类派生,而这些基类又从同一个基类派生,那么在访问此共同基类中的成员时,将产生二义性么在访问此共同基类中的成员时,将产生二义性采用虚基类来处采用虚基类来处理。理。虚基类虚基类虚基类的引入虚基类的引入用于有共同基类的场所用于有共同基类的场所声明
23、声明以以virtual修饰阐明基类修饰阐明基类例:例:class B1:virtual public B作用作用主要用来处理多承继时能够发生的对同一基类承继多次而产生的二主要用来处理多承继时能够发生的对同一基类承继多次而产生的二义性问题义性问题.为最远的派生类提供独一的基类成员,而不反复产生多次拷贝为最远的派生类提供独一的基类成员,而不反复产生多次拷贝留意:留意:在第一级承继时就要将共同基类设计为虚基类。在第一级承继时就要将共同基类设计为虚基类。例例 虚基类举例虚基类举例D1类类void fund ;int nVd;B1类类int nV1;D1类类void fun ;void fund ;in
24、t nv;int B1:nV1;int B2:nV2;int nVd;B2类类int nV2;B0类类Void fun ;int nV;B0B1新增成员新增成员B0B2新增成员新增成员D1新增成员新增成员B0B0B1B2D1nV, fun #include class B0/声明基类声明基类B0public: /外部接口外部接口int nV;void fun coutMember of B0endl;class B1: virtual public B0 /B0为虚基类,派生为虚基类,派生B1类类public: /新增外部接口新增外部接口int nV1;class B2: virtual pu
25、blic 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 ;虚基类及其派生类构造函数虚基类及其派生类构造函数建立对象时所指定的类称为最远派生类。建立对象时所指定的类称为最远派生类。虚基类的成员是由最
26、远派生类的构造函数经过调用虚基类的构造虚基类的成员是由最远派生类的构造函数经过调用虚基类的构造函数进展初始化的。函数进展初始化的。在整个承继构造中,直接或间接承继虚基类的一切派生类,都必在整个承继构造中,直接或间接承继虚基类的一切派生类,都必需在构造函数的成员初始化表中给出对虚基类的构造函数的调用。假需在构造函数的成员初始化表中给出对虚基类的构造函数的调用。假设未列出,那么表示调用该虚基类的缺省构造函数。设未列出,那么表示调用该虚基类的缺省构造函数。在建立对象时,只需最远派生类的构造函数调用虚基类的构造函在建立对象时,只需最远派生类的构造函数调用虚基类的构造函数,该派生类的其它基类对虚基类构造函数的调用被忽略。数,该派生类的其它基类对虚基类构造函数的调用被忽略。有虚基类时的构造函数举例有虚基类时的构造函数举例#include class B0/声明基类声明基类B0 public:/外部接口外部接口B0(int n) nV=n;int nV;void fun coutMember of B0endl;class B1: virtual public B0 public:B
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业人力资源规划分析报告工具
- 行业采购合同模板及条款解析
- 标准化招聘流程指导手册
- 客户售后服务标准化流程卡片
- 企业培训资源分配模板
- 小黄猫的故事童话作文12篇范文
- 线上商城商品质量保证承诺书9篇范文
- 可持续发展措施坚定执行承诺书5篇
- 合同审查及风险控制标准操作模板
- 远程办公高效沟通协作平台操作指南
- 应急计划评审表
- 配电房岗位职责
- 2024-2025华为ICT大赛(实践赛)-网络赛道理论考试题库大全-上(单选题)
- 应急第一响应人理论考试试卷(含答案)
- 人教版数学一年级上册 前后上下左右专项练习题(试题)
- 考察探究皮影戏进校园综合实践活动方案
- 股票入门基础知识培训
- 学校第三方协议书的范本
- FlowmasterV7中文技术手册
- 变电站电气安全工作规程
- (完整版)冠词练习题及答案
评论
0/150
提交评论