欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    经济学继承与派生类.pptx

    • 资源ID:87323950       资源大小:521.58KB        全文页数:140页
    • 资源格式: PPTX        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    经济学继承与派生类.pptx

    第5章继承与派生类5.1 继承与派生类5.2 派生类的构造函数和析构函数*5.3 调整基类成员在派生类中的访问属性的其他方法5.4 多继承5.5 赋值兼容原则5.6 程序举例5.7 本章小结第1页/共140页5.1继承与派生类5.1.1 为什么要使用继承5.1.2 派生类的声明5.1.3 基类成员在派生类中的访问属性5.1.4 派生类对基类成员的访问规则第2页/共140页5.1.1为什么要使用继承继承是自然界的一个普遍的重要特性。派生使新类在继承共性的同时,具有了更加丰富多彩的个性。第3页/共140页继承的层次结构面向对象程序设计的继承与派生机制是源于自然界中的概念。一般采用层次分类方法来描述事物之间的关系。第4页/共140页简单的汽车分类图第5页/共140页类的层次结构关系总结类的层次结构图中,下层类是上层类的特殊类。下层类自动具有上层类的特性,同时也具有自身新的特性。越往层次结构图的下层,其特性越具体化这种从上到下的层次结构关系体现了继承与派生的过程。C+面向对象技术也采用了这种继承机制。第6页/共140页Persong类和Employee类classpersonprotected:charname10;intage;charsex;public:voidprint();classemployeeprotected:charname10;intage;charsex;chardepartment20;floatsalary;public:voidprint();返回返回第7页/共140页5.1.2派生类的声明/定义一个基类classpersonprotected:charname10;intage;charsex;public:/;/定义一个派生类classemployee:publicpersonprotected:chardepartment20;floatsalary;public:/;第8页/共140页C+派生类的定义格式class派生类名:继承方式基类名派生类新定义的数据成员;派生类新定义的成员函数;第9页/共140页继承方式继承方式有三种:public 公有继承private 私有继承protected 保护继承缺省情况下表示private方式第10页/共140页由类person继承出类employee可以采用下面的三种格式之一:(1)公有继承classemployee:publicperson/;(2)私有继承classemployee:privateperson/;(3)保护继承classemployee:protectedperson/;第11页/共140页派生类的生成过程派生类的生成过程经历了三个步骤:吸收基类成员 改造基类成员 添加派生类新成员第12页/共140页吸收基类成员在C+的继承机制中,派生类吸收基类中除构造函数和析构函数之外的全部成员。吸收基类成员是一个重用的过程,体现了代码的重用。第13页/共140页改造基类成员由于基类的部分成员在派生类中可能不需要却也被继承下来,对这些没有实际需要而被继承的成员,在派生类中需要对其进行改造。改造基类成员包括两个方面:(1)通过派生的三种继承方式来控制;(2)通过在派生类中定义同名成员(包括成员函数 和数据成员)来屏蔽在派生类中不起作用的部 分基类成员。第14页/共140页添加派生类新成员添加派生类的新成员是继承机制的核心内容。仅仅继承基类的成员是不够的,需要在派生类中添加新成员,以保证派生类自身特殊属性和行为的实现。返回返回第15页/共140页5.1.3基类成员在派生类中的访问属性在基类中的访问属性继承方式在派生类中的访问属性privatepublic不可直接访问privateprivate不可直接访问privateprotected不可直接访问publicpublicpublicpublicprivateprivatepublicprotectedprotectedprotectedpublicprotectedprotectedprivateprivateprotectedprotectedprotected第16页/共140页三种继承方式的属性表公有成员私有成员保护成员公有继承公有不可访问保护私有继承私有不可访问私有保护继承保护不可访问保护继承方式继承方式基类成员基类成员返回返回第17页/共140页5.1.4派生类对基类成员的访问规则派生类对基类成员的访问形式主要有以下两种:(1)内部访问:由派生类中新增成员对基类继承来的成员的访问。(2)对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问。第18页/共140页1.私有继承的访问规则当类的继承方式为私有继承时,基类的public成员和protected成员被继承后作为派生类的private成员,派生类的其他成员可以直接访问它们,但是在类外部通过派生类的对象无法访问。基类的private成员在私有派生类中是不可直接访问的,所以无论是派生类成员还是通过派生类的对象,都无法直接访问从基类继承来的private成员,但是可以通过基类提供的public成员函数间接访问。第19页/共140页例5.1一个私有继承的例子#includeclassbase/声明一个基类public:voidsetx(intn)x=n;voidshowx()coutxendl;private:intx;第20页/共140页例5.1一个私有继承的例子classderived:privatebase/声明一个私有派生类public:voidsetxy(intn,intm)setx(n);/setx()在派生类中为private成员,派生类成员函数可以访问y=m;voidshowxy()coutx;/非法,在派生类中不能直接访问基类的私有成员xcoutyendl;private:inty;showx();第21页/共140页例5.1一个私有继承的例子voidmain()derivedobj;obj.setx(10);/非法,setx()在派生类中为private成员,派生/类对象不能访问obj.showx();/非法,showx()在派生类中为private成员,派生/类对象不能访问obj.setxy(20,30);obj.showxy();base base_obj;base_obj.setx(10);base_obj.showx();第22页/共140页例5.2保护成员以私有方式继承后的访问属性#includeclassbase/声明一个基类public:voidseta(intsa)a=sa;voidshowa()couta=aendl;protected:inta;第23页/共140页例5.2保护成员以私有方式继承后的访问属性classderive1:privatebase/声明一个私有派生类public:voidsetab(intsa,intsb)a=sa;b=sb;voidshowab()couta=aendl;coutb=bendl;protected:intb;第24页/共140页例5.2保护成员以私有方式继承后的访问属性classderive2:privatederive1/声明一个私有派生类public:voidsetabc(intsa,intsb,intsc)setab(sa,sb);c=sc;voidshowabc()cout“a=”aendl;/非法,a在类derive2中为不可直接访/问成员coutb=bendl;/合法,b在类derive2中为private成员coutc=cendl;private:intc;若将其改为showa();呢?将其改为:void showabc()showab();cout“c=”cendl;第25页/共140页例5.2保护成员以私有方式继承后的访问属性voidmain()baseop1;op1.seta(1);op1.showa();derive1op2;op2.setab(2,3);op2.showab();derive2op3;op3.setabc(4,5,6);op3.showabc();第26页/共140页表5-2私有继承的访问规则基类成员private成员public成员protected成员内部访问对象访问不可访问不可访问可访问不可访问可访问不可访问第27页/共140页2.公有继承的访问规则当类的继承方式为公有继承时,基类的public成员和protected成员被继承到派生类中仍作为派生类的public成员和protected成员,派生类的其他成员可以直接访问它们。但是,类的外部使用者只能通过派生类的对象访问继承来的public成员。基类的private成员在公有派生类中是不可直接访问的,所以无论是派生类成员还是通过派生类的对象,都无法直接访问从基类继承来的private成员,但是可以通过基类提供的public成员函数间接访问它们。第28页/共140页例5.3公有继承的访问规则#includeclassbase/声明一个基类public:voidsetxy(intm,intn)x=m;y=n;voidshowxy()coutx=xendl;couty=yendl;private:intx;protected:inty;第29页/共140页例5.3公有继承的访问规则classderived:publicbase/声明一个公有派生类public:voidsetxyz(intm,intn,intl)setxy(m,n);/setxy()在派生类中是public成员,可以访问z=l;voidshowxyz()coutx=xendl;/非法,x在类derived中为不可直接访问成员couty=yendl;/合法,y在类derived中为protected成员coutz=zendl;private:intz;showxy();第30页/共140页例5.3公有继承的访问规则voidmain()derivedobj;obj.setxyz(30,40,.50);obj.showxy();/合法,showxy()在类derived中为public成员obj.showxyz();第31页/共140页表5-3公有继承的访问规则基类成员Private成员public成员protected成员内部访问对象访问不可访问不可访问可访问可访问可访问不可访问第32页/共140页3.保护继承的访问规则当类的继承方式为保护继承时,基类的public成员和protected成员被继承到派生类中都作为派生类的protected成员,派生类的其他成员可以直接访问它们,但是类的外部使用者不能通过派生类的对象来访问它们。基类的private成员在保护派生类中是不可直接访问的,所以无论是派生类成员还是通过派生类的对象,都无法直接访问基类的private成员。第33页/共140页例5.4保护继承的访问规则#includeclassBase/声明一个基类public:intz;voidsetx(inti)x=i;intgetx()returnx;private:intx;protected:inty;第34页/共140页例5.4保护继承的访问规则classDerived:protectedBase/声明一个保护派生类public:intp;voidsetall(inta,intb,intc,intd,inte,intf);voidshow();private:intm;protected:intn;第35页/共140页例5.4保护继承的访问规则voidDerived:setall(inta,intb,intc,intd,inte,intf)x=a;/非法,在类Derived中,x为不可直接访问成员y=b;/合法,y在类Derived中为protected成员z=c;/合法,z在类Derived中为protected成员m=d;n=e;p=f;setx(a);第36页/共140页例5.4保护继承的访问规则voidDerived:show()cout“x=”xendl;/非法,在类Derived中,/x为不可直接访问成员cout“x=”getx()endl;/合法,getx()在类Derived中/为protected成员couty=yendl;/合法,y在类Derived中为protected成员coutz=zendl;/合法,z在类Derived中为protected成员coutm=mendl;coutn=nendl;第37页/共140页例5.4保护继承的访问规则voidmain()Derivedobj;obj.setall(1,2,3,4,5,6);obj.show();coutp=obj.pendl;/合法,p在类Derived中为public成员第38页/共140页表5-4保护继承的访问规则基类成员private成员public成员protected成员内部访问对象访问不可访问不可访问可访问不可访问可访问不可访问返回返回第39页/共140页5.2派生类的构造函数和析构函数基类的构造函数的功能是创建基类对象并进行初始化,而析构函数的功能在基类对象生存期结束时对基类对象进行必要的清理工作。在派生类的生成过程中,派生类将产生新的成员,对新增数据成员的初始化需要由派生类自身的构造函数完成,而对派生类对象的清理工作需要由相应的析构函数完成。第40页/共140页5.2派生类的构造函数和析构函数5.2.1 派生类构造函数和析构函数的执行顺序5.2.2 派生类构造函数和析构函数的构造规则第41页/共140页5.2.1派生类构造函数和析构函数的执行顺序通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数。当撤消派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。第42页/共140页例5.5基类和派生类的构造函数及析构函数的执行顺序#includeclassBase public:Base()coutConstructingbaseclassn;/基类的构造函数Base()coutDestructingbaesclassn;/基类的析构函数;第43页/共140页例5.5基类和派生类的构造函数及析构函数的执行顺序classDerive:publicBasepublic:Derive()coutConstructingderivedclassn;/派生类的构造函数Derive()coutDestructingderivedclassn;/派生类的析构函数;voidmain()Deriveop;返回返回第44页/共140页5.2.2派生类构造函数和析构函数的构造规则当基类中没有显式定义构造函数时,派生类的构造函数定义可以省略,系统采用默认的构造函数。当基类定义了具有形参的构造函数时,派生类也必须定义构造函数,提供将参数传递给基类构造函数的途径,使基类对象在进行初始化时可以获得相关数据。第45页/共140页C+中派生类构造函数的一般格式派生类名(参数总表):基类名(参数表)/派生类新增成员的初始化语句第46页/共140页例5.6当基类含有带参数的构造函数时,派生类构造函数的构造方法。#includeclassBasepublic:Base(intn)/基类的构造函数coutConstructingbaseclassn;i=n;Base()/基类的析构函数coutDestructingbaseclassn;voidshowi()coutiendl;private:inti;第47页/共140页例5.6当基类含有带参数的构造函数时,派生类构造函数的构造方法。classDerive:publicBasepublic:Derive(intn,intm):Base(m)/定义派生类构造函数时,/缀上基类的构造函数coutConstructingderivedclassendl;j=n;Derive()/派生类的析构函数coutDestructingderivedclassendl;voidshowj()coutjendl;private:intj;voidmain()Deriveobj(50,60);obj.showi();obj.showj();第48页/共140页当派生类中含有内嵌对象成员时,其构造函数的一般形式派生类名派生类名(参数总表参数总表):):基类名基类名(参数表参数表1),1),内嵌对象名内嵌对象名1(1(内嵌对象参数表内嵌对象参数表1),1),内嵌对象名内嵌对象名n(n(内嵌对象参数表内嵌对象参数表n)n)/派生类新增成员的初始化语句派生类新增成员的初始化语句 第49页/共140页在定义派生类对象时,构造函数的执行顺序调用基类的构造函数调用基类的构造函数;调用内嵌对象成员的构造函数(有多个对象成员时调用内嵌对象成员的构造函数(有多个对象成员时,调用顺序由它们在类中声明调用顺序由它们在类中声明的顺序确定)的顺序确定);派生类的构造函数体中的内容。派生类的构造函数体中的内容。撤消对象时,析构函数的调用顺序与构造函数的调用顺序正好相反。第50页/共140页例5.7内嵌对象成员的例子#includeclassBasepublic:Base(inti)/基类的构造函数coutConstructingbaseclassn;x=i;Base()/基类的析构函数coutDestructingbaseclassn;voidshow()coutx=xendl;private:intx;第51页/共140页例5.7内嵌对象成员的例子classDerive:publicBasepublic:Derive(inti):Base(i),d(i)/定义派生类构造函数时,/缀上基类的构造函数和对象成员构造函数coutConstructingderivedclassendl;Derive()/派生类的析构函数coutDestructingderivedclassendl;private:Based;/d为基类对象,作为派生类的对象成员;第52页/共140页例5.7内嵌对象成员的例子voidmain()Deriveobj(123);obj.show();第53页/共140页说明(1)当基类构造函数不带参数时,派生类不一定需要定义构造函数,然而当基类的构造函数哪怕只带有一个参数,它所有的派生类都必须定义构造函数。甚至所定义的派生类构造函数的函数体可能为空,仅仅起参数的传递作用。第54页/共140页说明(2)若基类使用缺省构造函数或不带参数的构造函数,则在派生类中定义构造函数时可略去“:基类构造函数名(参数表)”。此时,若派生类也不需要构造函数,则可不定义构造函数。(3)如果派生类的基类也是一个派生类,每个派生类只需负责其直接基类的构造,依次上溯。第55页/共140页说明(4)由于析构函数是不带参数的,在派生类中是否要定义析构函数与它所属的基类无关,基类的析构函数不会因为派生类没有析构函数而得不到执行,它们是各自独立的。返回返回第56页/共140页*5.3调整基类成员在派生类中的访问属性的其他方法5.3.1 同名成员5.3.2 访问声明第57页/共140页5.3.1同名成员第58页/共140页5.3.2访问声明第59页/共140页5.4多继承派生类只有一个基类,这种派生方法称为单基派生或单继承。当一个派生类具有多个基类时,这种派生方法称为多基派生或多继承。第60页/共140页5.4多继承5.4.1 多继承的声明5.4.2 多继承的构造函数和析构函数5.4.3 虚基类第61页/共140页5.4.1多继承的声明定义具有两个或两个以上基类的派生类与定义单继承是类似的。在多个基类及继承方式之间用逗号分隔。两个以上基类的派生类声明的一般形式如下:class派生类名:继承方式1基类名1,继承方式n基类名n/派生类新增的数据成员和成员函数;第62页/共140页多继承的定义应注意冒号之后为基类表,每一个基类名前都有继承方式。若缺省,系统默认为私有继承方式。实际上,派生类与每个基类之间的关系可以认为是一个单继承。多继承可以认为是单继承的自然拓展。第63页/共140页例5.12多继承情况下的访问特性#includeclassApublic:voidsetA(intx)a=x;voidprintA()couta=aendl;private:inta;第64页/共140页例5.12多继承情况下的访问特性classBpublic:voidsetB(intx)b=x;voidprintB()coutb=bendl;private:intb;第65页/共140页例5.12多继承情况下的访问特性classC:publicA,privateBpublic:voidsetC(intx,inty)c=x;setB(y);voidprintC()printB();coutc=cendl;private:intc;第66页/共140页例5.12多继承情况下的访问特性voidmain()Cobj;obj.setA(3);obj.printA();obj.setB(4);/错误obj.printB();/错误obj.setC(6,8);obj.printC();当删去这两句后,输出结果为:第67页/共140页说明对基类成员的访问必须是无二义性的,例如下列程序段对基类成员的访问是二义性的,必须想法消除二义性。第68页/共140页说明classXpublic:intf();classYpublic:intf();intg();classZ:publicx,publicYpublic:intg();inth();第69页/共140页各类及其成员关系图Y public:f();g();X public:f();Z X public:f();Y public:f();g();g();h();第70页/共140页说明如定义类Z的对象obj:Z obj;则以下对f()的访问是二义性的:obj.f();/二义性错误,不知调用的是X的f(),/还是Y的f()使用成员名限定可以消除二义性,例如:obj.X:f();/调用类X的f()obj.Y:f();/调用类Y的f()返回返回第71页/共140页5.4.2多继承的构造函数和析构函数多继承构造函数定义的一般形式如下:派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),基类名n(参数表n)/派生类新增成员的初始化语句第72页/共140页5.4.2多继承的构造函数和析构函数总参数表必须包含完成所有基类初始化需要的参数,各基类构造函数之间以逗号分隔。第73页/共140页多继承方式下构造函数的执行顺序先执行所有基类的构造函数再执行对象成员的构造函数最后执行派生类的构造函数内嵌对象成员的构造函数执行顺序与对象在派生类中声明的顺序一致,而处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的基类顺序,而与派生类构造函数中所定义的成员初始化列表顺序没有关系。第74页/共140页多继承方式下析构函数的执行顺序析构函数的执行顺序与多继承方式下构造函数的执行顺序完全相反,首先对派生类新增的数据成员进行清理,再对派生类对象成员进行清理,最后才对基类继承来的成员进行清理。第75页/共140页例5.13多继承中的构造函数的定义方法#includeclassBase1public:Base1(intsx)x=sx;intgetx()returnx;private:intx;第76页/共140页例5.13多继承中的构造函数的定义方法classBase2public:Base2(intsy)y=sy;intgety()returny;private:inty;第77页/共140页例5.13多继承中的构造函数的定义方法classDerived:publicBase1,privateBase2public:Derived(intsx,intsy,intsz):Base1(sx),Base2(sy)z=sz;intgetz()returnz;intgety()returnBase2:gety();private:intz;第78页/共140页例5.13多继承中的构造函数的定义方法voidmain()Derivedobj(1,3,5);intma=obj.getx();coutx=maendl;intmb=obj.gety();couty=mbendl;intmc=obj.getz();coutz=mcendl;返回返回第79页/共140页5.4.3虚基类一般情况下,在派生类中对基类成员的访问应该是惟一的。但在多继承方式下,可能造成对基类中某个成员的访问出现不惟一的情况,这种现象称为对基类成员访问的二义性问题。具体而言,二义性指在多继承方式下,派生类的某些数据成员可能出现多个副本,或成员函数出现多个映射地址等现象。第80页/共140页二义性的解决方法(1)使用作用域运算符“:”通过直接基类名进行限定,这种解决方法的特点是派生类中的同名成员依然具有多个副本,但通过基类名标识。(2)通过定义虚基类来解决,在多继承方式下,派生类的同名数据成员在内存中出现多个副本、同名成员函数出现多个地址映射,如果将直接基类的共同基类设置为虚基类,那么从不同的路径继承过来的同名成员在内存中只拥有一个副本,从而解决了同名成员的二义性问题。第81页/共140页例5.14虚基类的引例#includeclassbasepublic:base()a=5;coutbasea=aendl;protected:inta;base protected:int a;第82页/共140页例5.14虚基类的引例classbase1:publicbasepublic:base1()a=a+10;coutbase1a=aendl;classbase2:publicbasepublic:base2()a=a+20;coutbase2a=aendl;base1 base protected:int a;base2 base protected:int a;第83页/共140页例5.14虚基类的引例classderived:publicbase1,publicbase2public:derived()coutbase1:a=base1:aendl;coutbase2:a=base2:aendl;base2 base protected:int a;base1 base protected:int a;derived第84页/共140页例5.14虚基类的引例main()derivedobj;return0;第85页/共140页图5-2非虚基类的类层次图 basebasebase1base2derived第86页/共140页虚基类的概念虚基类的定义需要通过关键字virtual限定,虚基类的声明是在派生类的声明过程中,其语法形式为:class派生类名:virtual继承方式类名/第87页/共140页虚基类的概念 在定义了虚基类以后,派生类对象中只存在一个虚基类成员的副本。第88页/共140页例5.15虚基类的使用#includeclassbasepublic:base()a=5;coutbasea=aendl;protected:inta;base protected:int a;第89页/共140页例5.15虚基类的使用classbase1:virtualpublicbasepublic:base1()a=a+10;coutbase1a=aendl;classbase2:virtualpublicbasepublic:base2()a=a+20;coutbase2a=aendl;base1 base protected:int a;base2 base protected:int a;第90页/共140页例5.15虚基类的使用classderived:publicbase1,publicbase2public:derived()coutderiveda=aendl;voidmain()derivedobj;base protected:int a;derivedderivedbase2 base1 第91页/共140页图5-3虚基类的类层次图 basebase1base2derived第92页/共140页虚基类的初始化1在使用虚基类时应该注意以下几点:(1)如果在虚基类中定义有带形参的构造函数,并且没有定义缺省形式的构造函数,则整个继承结构中,所有直接或间接的派生类都必须在构造函数的成员初始化表中列出对虚基类构造函数的调用,以初始化在虚基类中定义的数据成员。第93页/共140页虚基类的初始化2(2)建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。该派生类的其他基类对虚基类构造函数的调用都自动被忽略。(对类层次结构图自左向右按深度优先遍历算法初始化)第94页/共140页虚基类的初始化3(3)若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数;(4)对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下;第95页/共140页虚基类的初始化4(5)对于非虚基类,构造函数的执行顺序仍是先左后右,自上而下;(6)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。第96页/共140页例5.16含有虚基类的派生类构造函数执行顺序#includeclassbasepublic:base(intsa)a=sa;coutConstructingbaseendl;private:inta;第97页/共140页例5.16含有虚基类的派生类构造函数执行顺序classbase1:virtualpublicbasepublic:base1(intsa,intsb):base(sa)b=sb;coutConstructingbase1endl;private:intb;第98页/共140页例5.16含有虚基类的派生类构造函数执行顺序classbase2:virtualpublicbasepublic:base2(intsa,intsc):base(sa)c=sc;coutConstructingbase2endl;private:intc;第99页/共140页例5.16含有虚基类的派生类构造函数执行顺序classderived:publicbase1,publicbase2public:derived(intsa,intsb,intsc,intsd):base(sa),base1(sa,sb),base2(sa,sc)d=sd;coutConstructingderivedendl;private:intd;voidmain()derivedobj(2,4,6,8);第100页/共140页说明(1)关键字virtual与继承方式关键字(public或private)的先后顺序无关紧要,它只说明是“虚拟继承”。例如以下两个虚拟继承的声明是等价的。classderived:virtualpublicbase/.;classderived:publicvirtualbase/.;第101页/共140页说明(2)一个基类在作为某些派生类虚基类的同时,又作为另一些派生类的非虚基类,这种情况是允许存在的。例如:classB.;classX:virtualpublicB.;classY:virtualpublicB.;classZ:publicB.;classAA:publicX,publicY,publicZ.;第102页/共140页图5-4具有虚基类和非虚基类的类层次图 B B X Y Z AA第103页/共140页说明 所以,为了保证基类成员在派生类中只继承一次,就必须将含有公共基类的直接派生类都说明为按虚拟方式派生。否则,除从用作虚拟派生的各路径中得到一个拷贝外,还从其他作为非虚拟派生的路径中各得到一个拷贝。返回返回第104页/共140页5.5赋值兼容规则 所谓赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。这样,公有派生类实际上就具备了基类的所有特性,凡基类能解决的问题,公有派生类也能解决。第105页/共140页5.5赋值兼容原则1.单基派生情形2.多基派生情形3.含有公共虚基类的类层次结构第106页/共140页1.单基派生情形例如,下面声明的两个类:classBase;classDerived:publicBase;根据赋值兼容规则,以下几种情况是合法的:第107页/共140页1.单基派生情形(1)可以用派生类对象给基类对象赋值。例如:Baseb;Derivedd;b=d;这样赋值的效果是,对象b中所有数据成员都将具有对象d中对应数据成员的值。第108页/共140页1.单基派生情形(2)可以用派生类对象来初始化基类的引用 例如:Derivedd;Base&br=d;第109页/共140页1.单基派生情形(3)可以把派生类对象的地址赋值给指向基类的指针例如:Derivedd;Base*bptr=&d;这种形式的转换在实际应用程序中最常见第110页/共140页1.单基派生情形(4)可以把指向派生类对象的指针赋值给指向基类对象的指针。例如:Derived*dptr;Base*bptr=dptr;第111页/共140页例5.17赋值兼容规则实例#includeclassBasepublic:inti;Base(intx)i=x;voidshow()coutBaseiendl;classDerived:publicBasepublic:Derived(intx):Base(x)voidshow()coutDerivedishow();Derived*d4=newDerived(55);Base*b4=d4;/把指向派生类对象的指针赋值给/指向基类对象的指针b4-show();deleted4;第114页/共140页说明(1)声明为指向基类对象的指针可以指向它的公有派生的对象,但不允许指向它的私有派生的对象。例如:classbase.;classderive:privatebase.;voidmain()baseop1,*ptr;/定义基类base的对象op1及指针ptrderiveop2;/定义派生类derive的对象op2ptr=&op1;/将指针ptr指向对象op1ptr=&op2;/错误,不允许将base类指针ptr指向它的私有派生类对象op2第115页/共140页说明(2)允许将一个声明为指向基类的指针指向其公有派生类的对象,但是不能将一个声明为指向派生类对象的指针指向其基类的一个对象。如下例第116页/共140页说明classBase.;classDerived:publicBase.;voidmain()Baseobj1;/定义基类对象obj1Derivedobj2,*ptr;/定义派生类对象obj2及指向派生类指针ptrptr=&obj2;/将指针ptr指向派生类对象obj2ptr=&obj1;/错误,试图将派生类指针指向基类对象第117页/共140页说明(3)声明为指向基类对象的指针,当其指向公有派生类对象时,只能用它来直接访问派生类中从基类继承来的成员,而不能直接访问公有派生类中定义的成员。如下例第118页/共140页说明classA/.public:voidprint1();classB:publicA/.public:print2();voidmain()Aop1,*ptr;/定义基类A的对象op1和基类指针ptr第119页/共140页说明Bop2;/定义派生类B的对象op2ptr=&op1;/将指针ptr指向基类对象op1ptr-print1();/调用基类函数print1();ptr=&op2;/将指针ptr指向派生类对象op2ptr-print1();/调用对象op2从基类继承来的成员函数ptr-print2()

    注意事项

    本文(经济学继承与派生类.pptx)为本站会员(莉***)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

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

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

    收起
    展开