《高级程序设计》PPT课件.PPT_第1页
《高级程序设计》PPT课件.PPT_第2页
《高级程序设计》PPT课件.PPT_第3页
《高级程序设计》PPT课件.PPT_第4页
《高级程序设计》PPT课件.PPT_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

高级程序设计,主 讲:李晓勇 Email: Telphone一、继承总结,继承方式: public : 公有继承 protected : 保护继承 private : 私有继承 访问控制属性: public : 公有类型 protected : 保护类型 private : 私有类型,继承方式与访问控制属性,公有继承: 基类的公有成员和保护成员作为派生类公有成员时,保持不变,但基类的私有成员不可访问。 私有继承: 基类的公有成员和保护成员作为派生类私有成员,变成私有,但基类的私有成员不可访问。 保护继承: 基类的公有成员和保护成员作为派生类保护成员,变成保护,但基类的私有成员不可访问。,不同继承方式的基类/派生类特性,基类/派生类的关系,任何一个类都可以派生出一个新类,派生类也可以派生出新的类,即一个基类是另一个基类的派生类,构成了类的层次结构。,A,B,C,A 是 B 的基类, B 是 C 基类; 称 B 是 A 的直接派生类; A 是 C 的间接基类;,二 、继承与构造函数/析构函数,1、问题: 类都有构造函数/析构函数,基类/派生类也有。 则 (1)派生类和基类的构造函数和析构函数是如何被调用的? (2)基类构造函数是如何获得实际参数的?,2、规则:,(1)派生类并不继承基类的构造/析构函数,相反派生类的构造函数必须向基类的构造函数提供实参。 (2)创建一个派生类的对象时,则先调用基类的构造函数,然后调用派生类的构造函数;派生类的对象被撤销时析构函数的调用次序相反。,3、派生类构造函数的形式,(): (参数),(参数) 例: B:B(int i ,int k):A(i) b=k; cout“Bs create“endl; ,初始化列表,举例:从vehicle(汽车)派生car(小汽车)类。,#include 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: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_passengers() return passenger_load; ;,void main() car bluebird(4,1000); /声明car类的对象 cout“The message of bluebird(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 A public: A() a=0; cout“As default create“endl; A(int i) a=i; cout“As create“endl; A() cout“As deleted“endl; void aprint() couta“,“; int geta() return a; private: int a; ;,class B: public A public: B() b=0;cout“Bs default create“endl; B (int i, int j, int k); B() cout“Bs deleted“endl; void print(); private: int b; A aa; /类成为数据成员 ; B: B(int i, int j, int k): A(i), aa(j) b=k; cout“Bs create“endl; ,void B:print() aprint(); coutb“,“aa.geta()endl; void main( ) B bb2; bb0= B(1,2,5); bb0.print(); ,As default create As default create Bs default create As default create As default create Bs default create As create As create Bs create Bs deleted As deleted As deleted 1,5,2 Bs deleted As deleted As deleted Bs deleted As deleted As deleted,结论: 创建一个派生类的对象时,构造函数的执行次序: (1)先调用基类的构造函数 (2)子对象类的构造函数 (3)派生类的构造函数 派生类的对象被撤销时,析构函数的执行次序: 析构函数的调用次序与构造函数相反。,三、同名覆盖原则 但派生类中存在同基类同名的成员时,派生类覆盖基类;可通过基类名加上”:”在派生类中对基类中的成员进行访问,#include class CA protected: int x,y; public: void set(int m, int n) x=m; y=n; ;,class CB: public CA protected: 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、概念 多继承(多重继承):为一个派生类指定多个基类。或者说,一个子类从多个基类中派生出来,它继承了多个类的基本特性。,2、派生类的定义,单继承派生类的定义格式: class : ; 多继承派生类的定义格式: class : , ;,说明: (1)派生类与每个类之间的关系仍可看作是一个单继承。 (2)多个基类中的成员相同时,通过子类的对象调用时,无法确定是哪一个基类的成员,容易产生二义性。,例, 床/沙发/折叠沙发,class bed / 多重继承 public : bed( ):weight(0) void sleep( ) cout“Sleeping.n“; void setweight( int i ) weight=i; protected: int weight; ; class sofa public: sofa( ): weight(0) void watchtv( ) cout“Watching tv.n“; void setweight(int i) weight=i; protected: int weight; ;,class sleepersofa : public bed, public sofa public: sleepersofa( ) void foldout( ) cout“Fold 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; cout“constructor B1.-“iendl; void print( ) coutb1endl; private: int b1; ; class B2 public: B2(int i) b2=i; cout“constructor B2.-“iendl; void print( ) coutb2endl; private: int b2; ; class B3 public: B3(int i)b3=i; cout“constructor B3.-“iendl; int getb3( ) return b3; private: int b3; ;,class A: public B2, public B1 public : A(int i, int j, int k, int m):B1(i),B2(j),bb(k) a=m; cout“constructor 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)派生类的构造函数,程序运行结果: constructor B2.-1 constructor B1.-2 constructor B3.-3 constructor A.-4 1 2 4,3,规则: (1)析构函数不能继承; (2)派生类中要定义自己的析构函数释放在派生中新增的成员; (3)从基类中继承的成员释放,可以通过基类的析构函数实现; (4)激活析构函数的顺序与构造函数缴活顺序相反。,例、多重继承与析构函数的关系,#include class B1 public: B1(int i) cout“constructor B1-“iendl; B1( )cout“destructing B1“endl; ; class B2 public: B2(int j) cout“constructor B2-“jendl; B2( )cout“destructing B2“endl; ; 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; ;,void main( ) C(1,2,5,8); ,小结:,(1)多重继承是一个类从多个基类派生。 (2)必须在派生类名和冒号之后,列出所有基类的类名,基类间用逗号隔开。 (3)派生类的构造函数必须激活所有基类的构造函数,并传送相应的参数。 (4)继承/多重继承一般是公有继承。保护继承/私有继承只是在技术讨论较多,实际使用较少。,五、多继承中同名覆盖原则,当派生类与基类中有同名成员时: 若未强行指名,则通过派生类对象使用的是派生类中的同名成员。 如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。,例 多继承同名覆盖举例,#include class B1 /声明基类B1 public: /外部接口 int nV; void fun( )cout“Member of B1“endl; ; class B2 /声明基类B2 public: /外部接口 int nV; void fun( )cout“Member of B2“endl; ; class D1: public B1, public B2 public: int nV; /同名数据成员 void fun( )cout“Member of D1“endl; /同名函数成员 ;,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( ); ,六、二义性问题,在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性(不确定性)采用虚函数或支配(同名覆盖)原则来解决。 当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性采用虚基类来解决。,虚基类,虚基类的引入 用于有共同基类的场合 声明 以virtual修饰说明基类 例:class B1:virtual public B 作用 主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题. 为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝 注意: 在第一级继承时就要将共同基类设计为虚基类。,例 虚基类举例,#include class B0 /声明基类B0 public: /外部接口 int nV; void fun( )cout“Member of B0“endl; ; class B1: virtual public B0 /B0为虚基类,派生B1类 public: /新增外部接口 int nV1; ;,class B2: virtual public B0 /B0为虚基类派生B2类 public: /新增外部接口 int nV2; ; class D1: public B1, public B2 /派生类D1声明 public: /新增外部接口 int nVd; void fund( )cout“Member of D1“endl; ; void main( ) /程序主函数 D1 d1; /声明D1类对象d1 d1.nV=2; /使用直接基类 d1.fun( ); ,虚基类及其派生类构造函数,建立对象时所指定的类称为最远派生类。 虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的缺省构造函数。 在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,该派生类的其它基类对虚基类构造函数的调用被忽略。,有虚基

温馨提示

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

评论

0/150

提交评论