第四章派生类与继承课件

上传人:文**** 文档编号:241945667 上传时间:2024-08-07 格式:PPT 页数:80 大小:407.18KB
返回 下载 相关 举报
第四章派生类与继承课件_第1页
第1页 / 共80页
第四章派生类与继承课件_第2页
第2页 / 共80页
第四章派生类与继承课件_第3页
第3页 / 共80页
点击查看更多>>
资源描述
第四章 派生类与继承(2)第四章 派生类与继承(2)表表4.1(1)基类中的私有成员基类中的私有成员 无论何种继承方式无论何种继承方式,派生类均不可直接访问派生类均不可直接访问(2)基类中的共有成员基类中的共有成员 根据继承方式而改变根据继承方式而改变(3)基类中的保护成员基类中的保护成员共有共有/保护保护 继承时不变继承时不变,私有继承时私有继承时 改变改变 4.1.3 4.1.3 基类成员在派生类中的访问属性基类成员在派生类中的访问属性表4.1 4.1.3 基类成员在派生类中的访问属性4.1.4 4.1.4 派生类对基类成员的访问规则派生类对基类成员的访问规则访问形式:内部访问内部访问 由派生类新增成员对基类继承来的成员进行访问.对象访问对象访问 在派生类外部,通过派生类对象对基类继承来的成员进行访问.4.1.4 派生类对基类成员的访问规则访问形式:1.私有继承的访问规则基类的基类的 public 和和 protected 成员被继承成员被继承后后,变成派生类的私有成员变成派生类的私有成员.派生类其他成员可直接访问派生类其他成员可直接访问(内部可访问内部可访问)外部通过派生类对象无法访问外部通过派生类对象无法访问1.私有继承的访问规则基类的 public 和 protec例:4.1private:X public:setx(int x)showx()private:Y public:setxy(int n,int m)showxy()base derive私有派生私有派生void showxy()cout x;cout yendl;例:4.1private:X private:Y 例例4.24.2protected:a public:seta(int sa)showa()protected:b public:seta(int sa,int sb)showab()protected:c public:seta(int sa,int sb,int sc)showabc()base derive1 derive2私有派生私有派生私有派生私有派生例4.2protected:a protected:b 1.私有继承的访问规则表 4.2内部可访问基类的public和protected成员外部对象对基类成员均不能访问。1.私有继承的访问规则表 4.22.公有继承的访问规则公有继承基类所有成员 (不变)内部可访问:基类的public 和 protected外部可访问:基类的public基类的private 内外都不能直接访问;2.公有继承的访问规则公有继承基类所有成员 (不变)例 4.3private:xprotected:y public:setxy()showxy()private:z public:setxyz()showxyz()base derive公有派生公有派生void setxyz(int m,int n,int j)setxy(m,n);Z=j;void showxyz()cout xendl;cout yendl;cout zendl;例 4.3private:xprivate:z 2.公有继承的访问规则表4.3内部可访问基类的public和protected成员外部对象可访问:基类的public基类的private 内外都不能直接访问;2.公有继承的访问规则表4.33.保护继承的访问规则基类的public和protected成员,通过保护继承作为派生类中的protected成员基类的private成员(不变),派生类无论内部还是外部均不可直接访问。3.保护继承的访问规则基类的public和protected例 4.4 private:xprotected:y public:zsetx()getx()base derive保护继承保护继承private:mprotected:npublic:psetall()show()void setall(.)x=a;/setx(a);y=b;z=c;.例 4.4 private:x base 3.保护继承的访问规则表4.4内部可访问:基类的public和protected成员外部对象均不可直接访问基类成员。3.保护继承的访问规则表4.44.2 4.2 派生类的构造函数和析构函数派生类的构造函数和析构函数基类都有显式或隐式的构造函数和析构函数基类都有显式或隐式的构造函数和析构函数当创建一个派生类对象时,如何调用基类的当创建一个派生类对象时,如何调用基类的构造函数对基类数据初始化,以及在撤消派构造函数对基类数据初始化,以及在撤消派生类对象时,又如何调用基类的析构函数来生类对象时,又如何调用基类的析构函数来对基类对象的数据成员进行善后处理?对基类对象的数据成员进行善后处理?第四章派生类与继承课件4.2.1 4.2.1 派生类构造函数和析构函数的执行顺序派生类构造函数和析构函数的执行顺序 通常情况下,当创建派生类对象时通常情况下,当创建派生类对象时:当撤消派生类对象时,顺序相反当撤消派生类对象时,顺序相反执行基类的构造函数执行基类的构造函数执行派生类的构造函数执行派生类的构造函数执行派生类的析构函数执行派生类的析构函数执行基类的析构函数执行基类的析构函数执行基类的构造函数执行派生类的构造函数执行派生类的析构函数执第四章派生类与继承课件第四章派生类与继承课件4.2.2 4.2.2 派生类构造函数和析构函数的构造规则派生类构造函数和析构函数的构造规则 当基类的构造函数没有参数,或没有显式定义构造当基类的构造函数没有参数,或没有显式定义构造函数时,派生类可以不向基类传递参数,甚至可以不函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数。例定义构造函数。例4.54.5的程序就是由于基类的构造函的程序就是由于基类的构造函数没有参数,所以派生类没有向基类传递参数。数没有参数,所以派生类没有向基类传递参数。派生类派生类不能不能继承基类中的构造函数和析构函数继承基类中的构造函数和析构函数。当。当基类合有带参数的构造函数时,派生类必须定义构造基类合有带参数的构造函数时,派生类必须定义构造函数以提供把参数传递给基类构造函数的途径。函数以提供把参数传递给基类构造函数的途径。在在C+C+中,派生类构造函数的一般格式为:中,派生类构造函数的一般格式为:派生类构造函数名派生类构造函数名(参数表参数表):基类构造函数名:基类构造函数名(参数表参数表)4.2.2 派生类构造函数和析构函数的构造规则第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件当派生类中含有对象成员时当派生类中含有对象成员时,构造函数的一般形式:构造函数的一般形式:派生类构造函数名派生类构造函数名(参数表参数表):基类构造函数名:基类构造函数名(参参数表数表)、对象成员名、对象成员名1(1(参数表参数表),、对象成员名、对象成员名n n(参数表参数表)在定义派生类对象时,构造函数的执行顺序:在定义派生类对象时,构造函数的执行顺序:1.1.基类的构造函数基类的构造函数2.2.对象成员的构造函数对象成员的构造函数3.3.派生类的构造函数派生类的构造函数撤消对象时,析构函数的调用顺序与构造函数的调用撤消对象时,析构函数的调用顺序与构造函数的调用顺序正好相反。顺序正好相反。当派生类中含有对象成员时,构造函数的一般形式:第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件(1)(1)当基类构造函数不带参数时,派生类不一定当基类构造函数不带参数时,派生类不一定需要定义构造函数,然而当基类的构造函数那需要定义构造函数,然而当基类的构造函数那怕只带有一个参数,它所有的派生类都必须定怕只带有一个参数,它所有的派生类都必须定义构造函数,甚至所定义的派生类构造函数的义构造函数,甚至所定义的派生类构造函数的函数体可能为空,仅仅起参数的传递作用。函数体可能为空,仅仅起参数的传递作用。derived(int derived(int n n):base():base(n n)j=0;j=0;说明说明(1)当基类构造函数不带参数时,派生类不一定需要定义构造函数说明说明(2)(2)若基类使用缺省构造函数或不带参数的构若基类使用缺省构造函数或不带参数的构造函数,则在派生类中定义构造函数时可造函数,则在派生类中定义构造函数时可略去略去“:基类构造函数名:基类构造函数名(参数表参数表)”;此;此时若派生类也不需要构造函数,则可不定时若派生类也不需要构造函数,则可不定义构造函数。义构造函数。说明(2)若基类使用缺省构造函数或不带参数的构造函数,则在派(3)(3)如果派生类的基类也是一个派生类,则如果派生类的基类也是一个派生类,则每个派生类只需负责其直接基类的构造每个派生类只需负责其直接基类的构造,依次上溯。依次上溯。(4)(4)由于析构函数是不带参数的,在派生类由于析构函数是不带参数的,在派生类中是否要定义析构函数与它所属的基类无中是否要定义析构函数与它所属的基类无关,故基类的析构函数不会因为派生类没关,故基类的析构函数不会因为派生类没有析构函数而得不到执行,它们各自是独有析构函数而得不到执行,它们各自是独立的。立的。(3)如果派生类的基类也是一个派生类,则每个派生类只需负责其例题 4.8 Third()e=0;Third(int x,int y,int z):Second(x,y)e=z;Second():First(1,1)c=0;d=0Second(int x,int y):First(x+1,y+1)c=x;d=y例题 4.8 4.3 调整基类成员在派生类中访问属性的其他方法4.3.1 同名成员同名成员Y obj;obj.f();obj.x:f();在私有继承情况下,为了保证基类的一部在私有继承情况下,为了保证基类的一部分成员函数在派生类中也存在,必须在派分成员函数在派生类中也存在,必须在派生类中重新定义同名的成员。生类中重新定义同名的成员。4.3 调整基类成员在派生类中访问属性的其他方法4.3.1 4.3.2 访问声明访问声明例题例题 4.10 (提出问题)(提出问题)C+提供访问声明的特殊机制,可个别调提供访问声明的特殊机制,可个别调整基类的某些成员,使之在派生类中保持整基类的某些成员,使之在派生类中保持原来的访问属性。原来的访问属性。在派生类定义中加入访问声明:在派生类定义中加入访问声明:基类名基类名:成员名成员名;例题:例题:4.11(解决问题)(解决问题)4.3.2 访问声明例题 4.10 (提出问题)说明(1)数据成员也可以使用访问声明)数据成员也可以使用访问声明(2)访问声明不带类型和参数)访问声明不带类型和参数(3)基类私有成员)基类私有成员不能不能使用访问声明使用访问声明(4)对于基类中重载函数名,访问声明对)对于基类中重载函数名,访问声明对所有的同名函数都起作用。(慎重)所有的同名函数都起作用。(慎重)说明(1)数据成员也可以使用访问声明 前面我们介绍的派生类只有一个基类,前面我们介绍的派生类只有一个基类,这种派生方法称为这种派生方法称为单基派生单基派生或或单一继承单一继承。当。当一个派生类具有多个基类时,这种派生方法一个派生类具有多个基类时,这种派生方法称为称为多基派生多基派生或或多重继承多重继承。例如,用户界面。例如,用户界面所提供的窗口、滚动条、文本框以及多种类所提供的窗口、滚动条、文本框以及多种类型的按钮,所有这些组件都是通过类来支持型的按钮,所有这些组件都是通过类来支持的,若把这些类中的两个类或多个类合并,的,若把这些类中的两个类或多个类合并,则可产生一个新类,例如把窗口和滚动条合则可产生一个新类,例如把窗口和滚动条合并起来产生一个可滚动的窗口,这个可滚动并起来产生一个可滚动的窗口,这个可滚动的窗口就是由多重继承得来的。的窗口就是由多重继承得来的。4 44 4 多重继承多重继承 前面我们介绍的派生类只有一个基类,这种派生方法称为 在在c+c+中,声明具有两个以上基类中,声明具有两个以上基类的派生类与声明单基派生类的形式相的派生类与声明单基派生类的形式相似,只需将要继承的多个基类用似,只需将要继承的多个基类用逗号逗号分隔分隔即可,其声明的一般形式如下:即可,其声明的一般形式如下:4.3.1 4.3.1 多重继承的声明多重继承的声明 在c+中,声明具有两个以上基类的派生类与声明单基派第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件 说明说明对基类成员的访问必须是对基类成员的访问必须是:无二义的无二义的,必须想法消除二义性必须想法消除二义性。说明 main()Z obj;obj.f();main()假如定义类假如定义类Z的对象的对象obj,z obj;则以下对函数则以下对函数f()的访问是二义的:的访问是二义的:obj.f();二义性错误,不知调用的是类二义性错误,不知调用的是类x的的f(),还是类,还是类Y的的f()使用成员名限定可使用成员名限定可以消除二义性,例如:以消除二义性,例如:obj.X:f();调用类调用类x的的f()obj.Y:f();调月类调月类Y的的f()假如定义类Z的对象obj,多重继承构造函数的定义形式与单继承多重继承构造函数的定义形式与单继承构造函数约定义形式相似,只是构造函数约定义形式相似,只是n n个基类的个基类的构造函数之间用构造函数之间用“,”分隔。多重继承构造分隔。多重继承构造函数定义的一般形式如下:函数定义的一般形式如下:派生类构造函数名派生类构造函数名(参数表参数表):基类基类l l构造函构造函数名数名(参数表参数表),基类基类2 2构造函数名构造函数名(参数参数表表),基类基类n n构造函数名构造函数名(参数表参数表)/.4.3.2 4.3.2 多重继承的构造函数与析构函数多重继承的构造函数与析构函数 多重继承构造函数的定义形式与单继承构造函数约定义形式第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件第四章派生类与继承课件 多重继承的构造函数的执行顺序与多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同单继承构造函数的执行顺序相同:先执行基类的构造函数先执行基类的构造函数 再执行对象成员的构造函数再执行对象成员的构造函数,最后执行派生类构造函数最后执行派生类构造函数。在多个基类之间,则严格按照派生在多个基类之间,则严格按照派生类声明时从左到右的顺序来排列先后。类声明时从左到右的顺序来排列先后。而析构函数的执行顺序则刚好与构造函而析构函数的执行顺序则刚好与构造函数的执行顺序相反。数的执行顺序相反。构造构造/析构函数执行顺序析构函数执行顺序 多重继承的构造函数的执行顺序与单继承构造函数的1 1为什么要引入虚基类为什么要引入虚基类 当引用派生类的成员时,首先在派生当引用派生类的成员时,首先在派生类自身的作用域中寻找这个成员,如果类自身的作用域中寻找这个成员,如果没有找到则到它的基类中寻找。没有找到则到它的基类中寻找。如果一个派生类是从多个基类派生出来如果一个派生类是从多个基类派生出来的,而这些基类又有一个共同的基类,的,而这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性。中的成员时,可能会产生二义性。请看以下这段程序。请看以下这段程序。虚基类虚基类1为什么要引入虚基类虚基类protected:a public:base()public:base1()couta;PublicBaseBase1public:base2()couta;PublicBase2Derivedpublic:derived()cout show();delete d4;例 4.17Base b1(11);说明说明(1)声明为指向基类对象的指针可指向其公有声明为指向基类对象的指针可指向其公有派生类对象,不允许指向私有派生的对象。派生类对象,不允许指向私有派生的对象。(2)声明为指向派生类对象的指针声明为指向派生类对象的指针不能指向不能指向基基类的对象。类的对象。(3)声明为指向基类对象的指针,当其指向公声明为指向基类对象的指针,当其指向公有派生类对象时,有派生类对象时,只能直接访问只能直接访问派生类中派生类中从基类继承来的成员从基类继承来的成员说明(1)声明为指向基类对象的指针可指向其公有派生类对象,不将基类指针显式类型转换为派生类指针。将基类指针显式类型转换为派生类指针。(B*)ptr)-print2();正确正确public:void print1()public:print2()PublicABA*ptr;ptr -print2();将基类指针显式类型转换为派生类指针。PublicABA*4.6 应用举例应用举例例4.18Data_recEmployee StudentTeacher E_Strudent 4.6 应用举例例4.184.6 应用举例应用举例例4.19locationpointcirclesX Yshowhidemovetoshowhideexpand contractmoveto4.6 应用举例例4.19locationpointcirc
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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