第十二讲继承与派生.ppt

上传人:本田雅阁 文档编号:2564898 上传时间:2019-04-09 格式:PPT 页数:49 大小:653.51KB
返回 下载 相关 举报
第十二讲继承与派生.ppt_第1页
第1页 / 共49页
第十二讲继承与派生.ppt_第2页
第2页 / 共49页
第十二讲继承与派生.ppt_第3页
第3页 / 共49页
亲,该文档总共49页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第十二讲继承与派生.ppt》由会员分享,可在线阅读,更多相关《第十二讲继承与派生.ppt(49页珍藏版)》请在三一文库上搜索。

1、第十二讲 继承与派生,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,1.说明格式 class: private: protected: public: ;,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,基类说明表: 列出所有基类。,每个基类的说明格式为: ,派生方式分为: 公有派生,关键字为public; 保护派生,关键字为protected; 私有派生,关键字为p

2、rivate; 派生方式决定了从基类继承来的成员在派生类中的属性。(P256.表8),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,针对继承与派生的关系,应注意:,一个类可以派生出多个派生类。,一个类可有一个或多个基类,分别称为单一继承和多重继承。,派生类又可有派生类,称为多级继承。,继承关系不可循环。,基类的友元关系、构造函数、析构函数都不能被派生类继承。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,2.派生类的构造函数和析构函数,假设类A是类B的派生类,(1) 类A

3、对象的创建必然包含类B对象的创建。显然,类A对象也包含类B对象的私有成员。,(2) 类A对象的创建和释放和其基类对象及成员对象相联系。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,派生类对象的初始化: 需要对基类的数据成员、派生类自身所含对象成员的数据成员以及其它新增的数据成员同时进行初始化。,派生类构造函数的一般格式: (): ,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,初始化符表的格式: (), (), (), (),是与所指基类中某个构造函数的参数表。是与所属

4、类中某个构造函数的参数表。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,系统创建派生类对象的步骤:,(1)调用各基类的构造函数,调用顺序按照它们被继承时声明的顺序(从左至右)。,(2)如果派生类自身含有对象成员,就调用各对象成员的构造函数,调用顺序按照它们在派生类中声明时的顺序(从左至右)。,(3)调用派生类自身的构造函数。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,系统释放派生类对象的步骤:,(1)调用派生类自身的析构函数。,(2) 调用各对象成员的析构函数,调用

5、顺序按照它们在派生类中声明时的相反顺序(从右至左)。,(3)调用各基类的析构函数,调用顺序按照它们被继承时声明的相反顺序(从右至左)。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例1: 派生类的简单实例 Program 8-3.cpp (P.260),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,情况一:通过继承可使派生类A对象拥有基类B的对象。,情况二:通过类A中对象成员也可使类A对象拥有其它类B的对象。,两种情况之间的区别?,12.1 派生类 12.2 其他特征的

6、继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,在情况一中,派生类A的对象必然是基类B的对象。类A对象具有类B对象的一切特征;此外类A对象还具有类B没有的其它特征。(is a),在情况二中,成员对象(类B对象)是类A对象的组成部分。(has a),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,两点注意:,(1) 注意构造函数和析构函数的执行次序。,(2) 注意“组装”关系和继承关系不同决定的对象成员(或基类成员) 访问方式以及对其对象可施加操作方面的不同。,12.1 派生类 12.2 其他特征的继承关系 12.

7、3 派生关系中的二义性处理 12.4 多态性与虚函数,(1)“继承”关系中的调用方式: ,(2)“组装”关系中的调用方式: ,例2: 对基类对象(对象成员)中公有成员的调用方式,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,1.友元关系以及静态成员的继承,(2)当派生类从基类继承过来的成员原先是某类的友元,那么派生类的成员仍然是某类的友元。,友元关系的继承:,(1) 当基类含有友元成员时,该基类的派生类不一定含有上述友元成员。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数

8、,静态成员的继承:,(1) 基类中位于公有段或者保护段的静态成员,在派生类中仍然是静态成员。,(2) 静态成员的调用方式: :,(3) 无论创建多少某静态成员的对象,都只有一份拷贝,为基类和派生类的所有对象共享。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,2. 派生类对象间赋值操作的原则,(1) 如果派生类有自己的赋值运算符的重载定义,即按该重载函数处理。,(2) 如果派生类未定义自己的赋值操作,而基类定义了赋值操作,则系统自动定义派生类赋值操作,其中基类成员的赋值按基类定义的赋值操作进行。,12.1 派生类 12.2 其他特征

9、的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,(3) 如果派生类和基类都没有定义赋值操作,那么系统自动定义缺省赋值操作(按位拷贝)。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,3. 基类对象与派生类对象之间的赋 值关系,基类对象=派生类对象 只是将派生类对象中“共性成员” 赋值给基类对象。 反方向赋值不允许。,(2) 指向基类对象的指针=派生类对 象的地址 通过上述指针可直接访问基类成员部分,但只有经过指针类型强制转换才可访问非基类成员部分。 反方向赋值不允许。,12.1 派生类 12.2 其他特征的继

10、承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,4. 上述赋值规定的依据,在派生类对象创建后,其在内存中的存储形式是先存其基类的成员,再存自身的各成员。 因此,使用基类对象指针指向其派生类对象时,同指向一个基类对象的效果相同。但不能保证基类对象指针对于派生类自有成员实例的访问或调用。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例3. 赋值规定的简单示例 Program 8-4. (P. 264),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,1.

11、单一继承时基类与派生类间重名成员的处理,对派生类而言,不加类名限定时默认为是处理派生类成员,而要访问基类重名成员时,则必须通过类名限定。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例4. 单一继承时重名成员处理规定的简单示例 Program 8-5. cpp (P. 266),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,2. 多重继承时两基类间重名成员的处理,对派生类而言,不加类名限定时默认为是处理派生类成员,而要访问基类重名成员时,则必须通过类名限定。,12.1

12、派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,3. 多级继承时(非虚拟继承)包含两个基类实例情况的处理,多级混合继承情况下,若类CD从两条不同“路径”同时对类A进行了一般性继承(非虚拟继承)的话,则类D的对象中会同时包含着两个类CA的实例。此时,对类CD而言,要通过类名限定来指定访问两个类CA实例中的哪一个。,类CD,类CB1,类CB2,类CA,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,上述各类之间的继承关系,class CA class CB 1: public A clas

13、s CB2 : public A class CD : public CB1, public CB2,类CD对象的存储结构示意图,( ( (CA) CB1 ) ( (CA) CB2 ) CD ),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例5. 上述多级混合继承关系应用举例。(P.268),类CA人员类;类CB1学生类; 类CB2助教类;类CD学生助教类。,(2)类CA人员类;类CB1学生类; 类CB2工人类;类CD工人学生类。,(3) 类CA家具类;类CB1沙发类; 类CB2床类;类CD沙发床类。,12.1 派生类 12.2

14、其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,#include class A /基类A public: int a; A (int x) a=x; void showall() cout “a=“ a endl; ; class B: public A /派生类B public: int b; B(int x):A(x-1)b=x; ;,例6:使用实例,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,class C:public A /派生类C public: int c; C(int x):A(x

15、-1)c=x; ; class D:public B,public C public: int d; D(int x, int y, int z):B(x+1),C(y+2)d=z;,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,void showall() cout“C:a=“C:aendl; cout“B:a=“B:aendl; /*在类D定义范围内,要通过类名限定来指定访问两个类A实例中的哪一个*/ cout“b,c,d=“b“, “c“,” dendl; /b、c、d不重名,具有唯一性 ;,12.1 派生类 12.2 其他特

16、征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,void main() /主函数 D Dobj(101, 202, 909); Dobj.showall(); cout“-“endl; cout“Dobj.C:a=“Dobj.C:aendl; /访问类D的从C继承而来的a cout“Dobj.B:a=“Dobj.B:aendl; ,程序执行后的显示结果如下: C:a=203 B:a=101 b,c,d=102, 204, 909 - Dobj.C:a=203 Dobj.B:a=101,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 1

17、2.4 多态性与虚函数,1. 函数重载(overloading)与静态联编(static binding),函数重载(overloading)(第八讲) 允许多个不同函数使用同一个函数名,但要求这些同名函数具有不同的参数表。 参数表中的参数个数不同; 参数表中对应的参数类型不同; 参数表中不同类型参数的次序不同。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例7. 函数重载(overloading)的例子,int abs (int n) return (n0?-n:n); float abs (float n) if (f0) f

18、=-f; return f; ,系统对函数重载这种多态性的分辨与处理,是在编译阶段完成的 - 静态联编(static binding)。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,2. 函数超载(overriding)、虚函数(vir tual function)及动态联编(dynamic bin ding),(1) 函数超载(overriding),仅在基类与其派生类的范围内实现,允许多个不同函数使用完全相同的函数名、函数参数表以及函数返回类型。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理

19、 12.4 多态性与虚函数,(2) 虚函数(virtual function),在定义某一基类(或其派生类)时,若将其中的某一函数成员的属性说明为virtual,则称该函数为虚函数(virtual function)。,虚函数的使用与函数超载密切相关。若基类中某函数被说明为虚函数,则意味着其派生类中也要用到与该函数同名、同参数表、同返回类型、但函数(实现)体不同的同一个超载函数。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,class graphelem protected: int color; public: graphele

20、m(int col) color=col; virtual void draw() . ; /虚函数draw,每一个类都要“draw”出属于它的类对象图形 ;,例7. 虚函数(overloading)的实例 (P.274),12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,class line:public graphelem public: virtual void draw() . ; /虚函数draw,负责画出“line” . ; class circle:public graphelem public: virtual void

21、 draw() . ; /虚函数draw,负责画出“circle” .; class triangle:public graphelem public: virtual void draw() . ; /虚函数draw,负责画出“triangle” .;,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,(3) 动态联编(dynamic binding),与虚函数以及程序中使用指向基类的指针(变量)密切相关。,C+规定,基类指针可以指向其派生类的对象(也即,可将派生类对象的地址赋给其基类指针变量), 但反过来不可以。这一点正是函数超载及

22、虚函数用法的基础。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例9. 建立例8中类line、类circle以及类triangle的类对象,而后调用它们各自的draw函数“画出”它们。,方法1:直接通过类对象(由类对象可以唯一确定要调用哪个类的draw函数) line ln1; circle cir1; triangle tri1; ln1.draw(); /调用类line中draw函数 cir1.draw(); tri1.draw();,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4

23、多态性与虚函数,方法2:使用指向基类的指针(动态联编,要靠执行程序时其基类指针的“动态”取值来确定调用哪一个类的draw函数) graphelem *pObj; line ln1; circle cir1; triangle tri1; pObj=,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例10. 假设inte_algo为基类,其中说明了一个虚函数integrate,并在其三个派生类中,也说明了该虚函数integrate(使用不同方法计算定积分)。,那么,可使用函数integrateFunc来实现调用不同虚函数integrat

24、e的目的: void integrateFunc(inte_algo * p) /基类指针p可指向任一派生类的对象 p-integrate(); /调用的将是不同派生类的integrate函数 主调函数处使用: integrateFunc( );,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,在编译阶段,系统无法确定究竟要调用哪一个派生类的integrate。此种情况下,将采用动态联编方式来处理:在运行阶段,通过p指针的当前值,去动态地确定对象所属类,而后找到对应虚函数。,12.1 派生类 12.2 其他特征的继承关系 12.3 派

25、生关系中的二义性处理 12.4 多态性与虚函数,程序使用虚函数的优点在于:,可使程序简单易读。 使得程序模块间的独立性加强。 增加了程序的易维护性。 提高了程序中“信息隐藏”的等级。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,3.纯虚函数与抽象基类,如果不准备在基类的虚函数中做任何事情,则可使用如下的格式将该虚函数说明成纯虚函数: virtual =0;,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,纯虚函数不能被直接调用,它只为其派生类的各虚函数规定了一个一致的“原

26、型规格”(该虚函数的实现将在它的派生类中给出)。,含有纯虚函数的基类称为抽象基类。注意,不可使用抽象基类来说明并创建它自己的对象,只有在创建其派生类对象时,才有抽象基类自身的实例伴随而生。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,实际上,抽象基类是对它的各派生类共同点的抽象综合。抽象基类、各派生类的特有成员、对基类中纯虚函数的具体实现,三者共同构成具体的实用类型。,另外:如果一个抽象基类的派生类中没有定义基类中的纯虚函数、而只是继承了基类的纯虚函数,则这个派生类还是一个抽象基类(其中仍包含着继承而来的那个纯虚函数)。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,例11:虚函数实例。计算函数的定积分。(P.278),采用矩形法、梯形法以及simpson法来计算同一函数的定积分。 此三种方法均将区间a,b分为n等份,而后以不同方式求出各小段对应的小面积si,并将它们相加到一起来作为近似结果。,12.1 派生类 12.2 其他特征的继承关系 12.3 派生关系中的二义性处理 12.4 多态性与虚函数,课堂自习,8.1 P.251 8.7.2 P.283,作 业,思考题: 3, 9, 12, 14 (书面) 练习题:1, 4, 8 (上机),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1