《c继承与派生》PPT课件.ppt

上传人:wuy****n92 文档编号:77679439 上传时间:2023-03-16 格式:PPT 页数:47 大小:309.50KB
返回 下载 相关 举报
《c继承与派生》PPT课件.ppt_第1页
第1页 / 共47页
《c继承与派生》PPT课件.ppt_第2页
第2页 / 共47页
点击查看更多>>
资源描述

《《c继承与派生》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《c继承与派生》PPT课件.ppt(47页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第八章第八章 继承与派生继承与派生2022/10/291派生类的引入派生类的引入C+的类提供了良好的的类提供了良好的模块分解模块分解技术,技术,也具有也具有可重用软件可重用软件所期望的品质:它们所期望的品质:它们是相似一致的模块,通过信息隐藏,将是相似一致的模块,通过信息隐藏,将它们的它们的接口和实现接口和实现清楚地分开来。清楚地分开来。我们还希望在类的基础上能取得更好的我们还希望在类的基础上能取得更好的可重用性和可扩充性可重用性和可扩充性的目标。的目标。面向对象的面向对象的继承技术继承技术提供了实现上述目提供了实现上述目标的有力手段。标的有力手段。2022/10/292现实中的继承与派生现实

2、中的继承与派生在在自自然然界界中中,继继承承这这个个概概念念是是非非常常普普遍遍的的。例例如如:小小猫猫仔仔继继承承了了猫猫爸爸猫猫妈妈的的特特性性,所所以以长长的的是是猫猫鼻鼻子子猫猫眼眼,我我们不会把它错认为是小狗。们不会把它错认为是小狗。继继承承就就是是将将一一些些本本质质的的特特性性遗遗传传给给子子代代,使使后后代代在在很很大大程程度度上上具具有有与与父父代代相同的性质。相同的性质。子代同时还具有父代没有的特性。子代同时还具有父代没有的特性。2022/10/293再来看一个现实世界中的例子:再来看一个现实世界中的例子:Rectangle Square Diamond Parallelo

3、gramRectangle Square Diamond ParallelogramQuadrangleQuadrangle四四边边形形是是一一个个基基本本的的概概念念,矩矩形形、正正方方形形、菱菱形形和和平平行行四四边边形形都都是是派派生生的的概概念念,因因为为它它们们都都属属于于四四边边形形,它它们们继继承承了了四四边边形形的的所所有有性质,同时又扩充出各自的特性。性质,同时又扩充出各自的特性。2022/10/294从上面的例子可以看出从上面的例子可以看出:而而且且子子代代可可以以拥拥有有父父代代没没有有的的特特性性,这是这是可扩充的概念可扩充的概念。一一旦旦指指定定了了某某种种事事物物父

4、父代代的的本本质质特特征征,那那么么它它的的子子代代将将会会自自动动具具有有那那些些性性质质。这这就就是是一一种种朴朴素素的的可可重重用用的概念的概念。2022/10/295从软件设计的角度来看从软件设计的角度来看:基基于于已已有有的的类类,可可以以建建立立新新的的类类。这这个个新新的的类类既既重重用用已已有有类类的的功功能能,又又扩展扩展了新的功能。了新的功能。类类是是某某类类事事物物共共同同特特性性的的体体现现,它它对外提供了特定的功能。对外提供了特定的功能。2022/10/296C+的继承关系的继承关系继承就是在一个已经存在的类的基础上建继承就是在一个已经存在的类的基础上建立另一个新的类

5、。立另一个新的类。基类基类派生类派生类已存在的类称为已存在的类称为“基类基类”或或“父类父类”,新,新建立的类称为建立的类称为“派生类派生类”或或“子类子类”,如,如图所示:图所示:2022/10/297派生类的功能主要通过以下方式来体现:派生类的功能主要通过以下方式来体现:派生类的特性派生类的特性吸收基类成员吸收基类成员添加新成员添加新成员改造基类成员改造基类成员从从编编码码的的角角度度来来看看,派派生生类类从从基基类类中中以以较较低低的的代代价价换换来来了了较较大大的的灵灵活活性性。一一旦旦产产生生了了可可靠靠的的基基类类,只只需需要要调调试试派派生生类类中中所所作作的的修修改改即即可可。

6、派派生生类类可可以以对对继继承承的属性进行扩展、限制或改变。的属性进行扩展、限制或改变。2022/10/298单继承和多继承单继承和多继承单继承:派生类只有一个直接基类单继承:派生类只有一个直接基类ABC单继承单继承XYZ多继承多继承多继承:派生类有多个直接基类多继承:派生类有多个直接基类2022/10/299单继承派生类单继承派生类定义单继承派生类的语法格式:定义单继承派生类的语法格式:class 派生类名派生类名:基类名基类名/派生类新添加的成员派生类新添加的成员;“继继承承方方式式”可可以以是是public、private、以及以及 protected。虽虽然然继继承承了了基基类类的的所

7、所有有成成员员,但但是是派派生生类类并并非非都都能能访访问问基基类类的的所所有有成成员员,继继承承方方式式会影响派生类对基类中各种成员的引用。会影响派生类对基类中各种成员的引用。2022/10/2910公有派生类公有派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为public时,该类称为公有派生类。时,该类称为公有派生类。class 派生类名派生类名:public 基类名基类名/派生类新添加的成员派生类新添加的成员;2022/10/2911基类的成员在公有派生类中的引用权限基类的成员在公有派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有

8、派生类公有成员公有成员不可访问成员不可访问成员保护成员保护成员不可访问成员不可访问成员在类外不能被直接访问。在类外不能被直接访问。在派生类的类内不能被直接访问。在派生类的类内不能被直接访问。2022/10/2912举例:公有派生举例:公有派生class Baseint v1;public:int v2;Base(int a=0,int b=0)v1=a;v2=b;class Derived:public Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func()int sum1=v1+v2+v3+v4;int s

9、um2=v2+v3+v4;void main()Derived obj(5,6);obj.v2=8;/错误错误2022/10/2913私有派生类私有派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为private时,该类称为私有派生类。时,该类称为私有派生类。class 派生类名派生类名:private 基类名基类名/派生类新添加的成员派生类新添加的成员;2022/10/2914基类的成员在私有派生类中的引用权限基类的成员在私有派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员私有派生类私有派生类私有成员私有成员不可访问成员不可访问成员私有成员私有成员2

10、022/10/2915举例:私有派生举例:私有派生class Baseint v1;public:int v2;Base(int a=0,int b=0)v1=a;v2=b;class Derived:private Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func()int sum1=v1+v2+v3+v4;int sum2=v2+v3+v4;void main()Derived obj(5,6);obj.v2=8;/错误错误/错误错误2022/10/2916公有派生和私有派生的比较公有派生和私有派生的比

11、较虽虽然然派派生生类类继继承承了了基基类类所所有有的的成成员员,但但是是基基类类的的私私有有成成员员对对于于派派生生类类来来说说是是不不可见可见的,因此不能被派生类所访问。的,因此不能被派生类所访问。基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类公有成员公有成员不可访问成员不可访问成员保护成员保护成员私有派生类私有派生类私有成员私有成员不可访问成员不可访问成员私有成员私有成员2022/10/2917保护成员的引入保护成员的引入为为了了解解决决这这个个问问题题,C+专专门门设设置置了了保保护护成成员员,即即用用protected关关键键字字说说明的成员。明的成员。保

12、护成员的特性:保护成员的特性:能够被基类和派生类所访问。能够被基类和派生类所访问。和私有成员一样,类外不能访问。和私有成员一样,类外不能访问。2022/10/2918举例:保护成员举例:保护成员class Baseprotected:int v1;public:int v2;Base(int a=0,int b=0)v1=a;v2=b;class Derived:public Baseint v3;public:int v4;Derived(int a=0,int b=0)v3=a;v4=b;void func()int sum1=v1+v2+v3+v4;int sum2=v2+v3+v4;v

13、oid main()Derived obj(5,6);obj.v1=8;/错误错误/正确正确2022/10/2919保护派生类保护派生类在在声声明明派派生生类类时时将将继继承承方方式式指指定定为为protected时,该类称为保护派生类:时,该类称为保护派生类:class 派生类名派生类名:protected 基类名基类名/派生类新添加的成员派生类新添加的成员;2022/10/2920基类的成员在保护派生类中的引用权限基类的成员在保护派生类中的引用权限基类基类公有成员公有成员私有成员私有成员保护成员保护成员保护派生类保护派生类保护成员保护成员不可访问成员不可访问成员保护成员保护成员2022/1

14、0/2921小结小结不不同同的的继继承承方方式式,子子类类对对基基类类中中的的成成员的访问权限如下表所示:员的访问权限如下表所示:基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类 公有成员公有成员 不可访问成员不可访问成员保护成员保护成员保护派生类保护派生类 保护成员保护成员 不可访问成员不可访问成员保护成员保护成员私有派生类私有派生类 私有成员私有成员 不可访问成员不可访问成员私有成员私有成员2022/10/2922派生类与基类同名成员的访问方式派生类与基类同名成员的访问方式C+允允许许派派生生类类可可以以重重新新定定义义基基类类的的成成员员,此此时时称称派派生生

15、类类的的成成员员覆覆盖盖了了基基类类的的同名成员。同名成员。如如果果在在派派生生类类中中,想想使使用用基基类类的的同同名名成成员员,则则可可以以显显式式地地使使用用类类名名+限限定定符符的的方式,如下所示:方式,如下所示:基类名基类名:成员成员2022/10/2923举例举例class Baseprotected:int v1;public:int v2;Base(int a=0,int b=0)v1=a;v2=b;class Derived:public Baseint v2;public:int v3;Derived(int a=0,int b=0)v2=a;v3=b;void func(

16、)int sum1=v1+v2+v3;int sum2=v1+Base:v2+v3;void main()Derived obj(5,6);obj.v2=8;/错误错误obj.Base:v2=9;/使用的是使用的是Derived中的中的v2/使用的是使用的是Base中的中的v22022/10/2924派生类对象的构造和析构派生类对象的构造和析构派生类对象数据成员的构成:派生类对象数据成员的构成:从基类继承过来的数据成员从基类继承过来的数据成员派生类自定义的数据成员派生类自定义的数据成员如何初始化这几部分数据成员呢?如何初始化这几部分数据成员呢?基本数据类型基本数据类型类类型类类型如何析构派生类

17、对象?如何析构派生类对象?2022/10/2925单继承派生类的构造函数单继承派生类的构造函数派生类构造函数派生类构造函数(参数表参数表):基类构造函数基类构造函数(参数表参数表),对象成员对象成员1(参数表参数表),对象成员对象成员n(参数表参数表),/初始化自定义数据成员初始化自定义数据成员如果基类使用的是缺省的构造函数或不带参如果基类使用的是缺省的构造函数或不带参数的构造函数,那么在初始化列表中可以省数的构造函数,那么在初始化列表中可以省略略“基类构造函数基类构造函数(参数表参数表)“这一项。这一项。如果没有对象成员,那么在初始化列表中可如果没有对象成员,那么在初始化列表中可以省略以省略

18、“对象成员对象成员(参数表参数表)“这一项。这一项。2022/10/2926构造函数的调用顺序如下:构造函数的调用顺序如下:构造函数和析构函数的调用顺序构造函数和析构函数的调用顺序先调用基类构造函数;先调用基类构造函数;再调用对象成员所属类的构造函数;再调用对象成员所属类的构造函数;最后调用派生类构造函数;最后调用派生类构造函数;析构函数的调用顺序如下:析构函数的调用顺序如下:再调用对象成员所属类的析构函数;再调用对象成员所属类的析构函数;先调用派生类的析构函数;先调用派生类的析构函数;最后调用基类的析构函数;最后调用基类的析构函数;2022/10/2927举例举例class Base pub

19、lic:Base()cout“Base createdn”;class Derived:public Base public:Derived()cout“Derived createdn”;void main()Derived d;2022/10/2928请分析请分析class baseint x;public:base(int i):x(i)coutbasen;class derived:public baseint a;public:derived(int i):a(i*4),base(a)cout基基类类对对象象”,而而不不是是“基基类类对对象象-派派生生类对象类对象”?其他继承方式会有

20、以上规则吗?其他继承方式会有以上规则吗?2022/10/2931解决第一个问题解决第一个问题v1v1v2v2v1v1v2v2v3v3v4v4基类对象基类对象基类对象基类对象派生类对象派生类对象派生类对象派生类对象基类对象和派生类对象的内存布局方式基类对象和派生类对象的内存布局方式当当一一个个派派生生类类对对象象直直接接赋赋值值给给基基类类对对象象时时,不不是是所所有有的的数数据据都都赋赋给给了了基基类类对对象象,赋赋予予的的只只是是派派生生类类对对象象的的一一部部分分。这这部部分分叫叫做做派生类对象的派生类对象的“切片切片”(sliced)。2022/10/2932解决第二个问题解决第二个问题

21、回回忆忆一一下下不不同同的的继继承承方方式式,子子类类对对基基类类中中的成员的访问权限:的成员的访问权限:基类基类公有成员公有成员私有成员私有成员保护成员保护成员公有派生类公有派生类公有成员公有成员不可访问成员不可访问成员保护成员保护成员私有派生类私有派生类私有成员私有成员不可访问成员不可访问成员私有成员私有成员保护派生类保护派生类保护成员保护成员不可访问成员不可访问成员保护成员保护成员只只有有在在公公有有派派生生的的情情况况下下,才才有有可可能能出出现现“基基类类的的公公有有成成员员变变成成派派生生类类的的公公有有成成员员”的情况。的情况。2022/10/2933多继承派生类多继承派生类派生

22、类有多个直接基类,这叫多继承。派生类有多个直接基类,这叫多继承。QuadrangleQuadrangleDiamondDiamondSquareSquareRectangleRectangleQuadrangleQuadrangle2022/10/2934定义多继承派生类的语法格式:定义多继承派生类的语法格式:class 派生类名派生类名:基类名基类名1,基类名基类名2,/派生类新添加的成员派生类新添加的成员;2022/10/2935多继承派生类对象的构造和析构多继承派生类对象的构造和析构多继承派生类的构造函数:多继承派生类的构造函数:派生类名派生类名(参数表参数表):基类名基类名1(参数表参

23、数表1),基类名基类名2(参数表参数表2),对象成员对象成员1(参数表参数表3),对象成员对象成员2(参数表参数表4),/派生类新添加的成员派生类新添加的成员2022/10/2936派生类构造函数的执行顺序:派生类构造函数的执行顺序:先先执执行行所所有有基基类类的的构构造造函函数数(按按这这些些基基类类被被继继承承时时声声明明顺顺序序依依次次执执行行基基类类1、基类基类2的构造函数)。的构造函数)。最后执行派生类本身的构造函数。最后执行派生类本身的构造函数。再再执执行行对对象象成成员员所所属属类类的的构构造造函函数数(按按照这些对象成员在类中定义的顺序)。照这些对象成员在类中定义的顺序)。20

24、22/10/2937多继承中的二义性问题多继承中的二义性问题在在多多继继承承中中,一一个个类类不不可可以以重重复复成成为为另另一一个个类类的的直直接接基基类类,但但可可以以多多次次成成为为间间接接基基类类。此此时时派派生生类类访访问问基基类类成成员时可能出现二义性。员时可能出现二义性。访问共同基类的成员时可能出现二义性。访问共同基类的成员时可能出现二义性。访访问问不不同同基基类类的的具具有有相相同同名名字字成成员员时时可可能出现二义性。能出现二义性。2022/10/2938访问不同基类同名成员访问不同基类同名成员时的二义性时的二义性 class A public:int value;void

25、f();class B public:int value;void f();void g();class C:public A,public B public:void g();void h();void main()C C1;C1.f();C1.value=9;/出现二义性出现二义性/出现二义性出现二义性解决办法是用类名对成员加以限定,例如:解决办法是用类名对成员加以限定,例如:C1.A:f();或者或者C1.B:f();C1.A:value=9;或者或者C1.B:value=9;2022/10/2939访问共同基类成员时访问共同基类成员时的二义性的二义性 class Apublic:int

26、 a;void g();class B1:public Aint b1;class B2:public Aint b2;class C:public B1,public B2int c;public:int f();void main()C Cobj;=8;Cobj.A:a=9;();/出现二义性出现二义性/出现二义性出现二义性/出现二义性出现二义性解决办法:解决办法:Cobj.B1:a=9;或或 Cobj.B2:a=9;2022/10/2940以上类的关系如下图所示:以上类的关系如下图所示:A(a,g()B1(b1)A(a,g()B2(b2)C(f(),c)类类A 是派生类是派生类C 两条继

27、承路径上的一个两条继承路径上的一个公共基类公共基类,因此这个,因此这个公共基类会在派生类对象中产生公共基类会在派生类对象中产生两个基类子对象两个基类子对象。虽然可以通过类限定符的方式避免二义性,但问题的关键在虽然可以通过类限定符的方式避免二义性,但问题的关键在于我们于我们不需要不需要在派生类对象中存在多个基类对象的拷贝!在派生类对象中存在多个基类对象的拷贝!如果要使这个公共基类在派生类中只产生一个基类子对象,如果要使这个公共基类在派生类中只产生一个基类子对象,则需要将这个基类设置为则需要将这个基类设置为虚基类虚基类。2022/10/2941虚基类虚基类引引进进虚虚基基类类的的目目的的是是为为了

28、了解解决决二二义义性性问问题题,使使公公共共基基类类在在其其派派生生类类对对象象中中只只产产生一个基类子对象。生一个基类子对象。虚基类说明格式如下:虚基类说明格式如下:virtual 在在“继承方式继承方式”前面用关键字前面用关键字virtual来说明来说明2022/10/2942例子:虚基类的使用例子:虚基类的使用 class Apublic:int a;void g();class B1:virtural public Aint b1;class B2:virtural public Aint b2;class C:public B1,public B2int c;public:int f

29、();void main()C Cobj;=8;/或或Cobj.A:a=9;();2022/10/2943A(g(),a)B1(b1)B2(b2)C(f(),c)类类A,B1,B2 和和C之间的关系如下图所示:之间的关系如下图所示:虚虚基基类类子子对对象象被被合合并并成成一一个个子子对对象象,这这种种“合合并并”作用,使得可能出现的二义性被消除。作用,使得可能出现的二义性被消除。2022/10/2944请比较下面两种情况请比较下面两种情况class C:public B1,public B2int c;public:int f();class C:public B2,public B1int

30、c;public:int f();对于类对于类C而言,类而言,类A是类是类B2的的“假假”基类,是类基类,是类B1的的“真真”基类。基类。对于类对于类C而言,类而言,类A是类是类B1的的“假假”基类,是类基类,是类B2的的“真真”基类。基类。A(g(),a)B1(b1)B2(b2)C(f(),c)A(g(),a)A(g(),a)B1(b1)B2(b2)C(f(),c)A(g(),a)因此,虚基类只是一个相对的概念。因此,虚基类只是一个相对的概念。2022/10/2945虚基类对象的初始化虚基类对象的初始化虚基类构造函数的调用次序如下:虚基类构造函数的调用次序如下:虚基类的构造函数在非虚基类之前

31、调用。虚基类的构造函数在非虚基类之前调用。若若虚虚基基类类由由非非虚虚基基类类派派生生,则则遵遵守守先先调调用用基基类类构构造造函函数数,再再调调用用派派生生类类构构造造函函数数的的规则。规则。若若在在同同一一层层次次中中包包含含多多个个虚虚基基类类,那那么么虚虚基类构造函数按它们说明的次序调用。基类构造函数按它们说明的次序调用。2022/10/2946例子例子class base;class bas2;class level1:public base2,vitrual public base;class level2:public base2,vitrual public base;class toplevel:public level1,vitrual public level2;当声明当声明toplevel类的对象时,构造函数的调类的对象时,构造函数的调用次序为:用次序为:base base2 level2 base2 level1 toplevel2022/10/2947

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 初中资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁