第5章-继承与派生课件.ppt

上传人(卖家):晟晟文业 文档编号:4782285 上传时间:2023-01-10 格式:PPT 页数:74 大小:1.14MB
下载 相关 举报
第5章-继承与派生课件.ppt_第1页
第1页 / 共74页
第5章-继承与派生课件.ppt_第2页
第2页 / 共74页
第5章-继承与派生课件.ppt_第3页
第3页 / 共74页
第5章-继承与派生课件.ppt_第4页
第4页 / 共74页
第5章-继承与派生课件.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

1、1第第5章继承和派生章继承和派生本章重点:本章重点:v继承与派生的概念;继承与派生的概念;v派生类的构造函数和析构函数的执行顺序与规派生类的构造函数和析构函数的执行顺序与规则;则;v多继承的声明与实现;多继承的声明与实现;v基类成员访问原则;基类成员访问原则;v赋值兼容性;赋值兼容性;v虚基类的概念虚基类的概念;25.1继承与派生的概念继承与派生的概念 v继承继承是面向对象程序设计中重要的特性是面向对象程序设计中重要的特性v继承主要是指在己有类继承主要是指在己有类(基类基类)的基础上创建新类的基础上创建新类的过程,这个新类就是的过程,这个新类就是派生类派生类v派生类包含基类的成员,包括所有的数

2、据和操派生类包含基类的成员,包括所有的数据和操作,而且还可以增加新的成员作,而且还可以增加新的成员3单继承单继承图图5.1 5.1 单继承单继承 图图5.2 5.2 类的层次树型结构图类的层次树型结构图 4多继承多继承图图5.3 多继承多继承 图图5.4 单继承与多继承单继承与多继承 5class Student private:int number;char name20;public:Student()number=0;name0=0;Void SetValue(int n,char*s1)number=n;Strcpy(name,s1);void Print()cout”Number:”

3、numberendl;cout”Name:”nameendl;;6class UGStudent private:int number;char name20;int age;int grade;public:void Print()cout”Number:”numberendl;cout”Name:”nameendl;cout”Age:”ageendl;cout”Grade:”gradeendl;;75.2 派生类的声明派生类的声明 v类的继承关系可以用如下语法表示:类的继承关系可以用如下语法表示:class 派生类名派生类名:继承方式继承方式 基类名基类名 派生类成员声明派生类成员声明;v

4、基类的构造函数和析构函数不能被派生类继承基类的构造函数和析构函数不能被派生类继承v派生类要初始化基类的数据成员必须在构造函派生类要初始化基类的数据成员必须在构造函数中初始化数中初始化8【例【例5.1】用继承重新定义】用继承重新定义UGStudent类。类。/*05_01.cpp*/class UGStudent:public Studentprivate:int age;int grade;public:UGStudent()SetValue(0,”);age=0;grade=0;UGStudent(int n,char*s1,int a,int g)SetValue(n,s1);age=a;

5、grade=g;void PrintExtra()cout”Age:”ageendl;cout”Grade:”gradeendl;9用主函数进行测试用主函数进行测试:int main()UGStudent st1(100,”wang”,18,1);st1.Print();/调用基类的函数调用基类的函数st1.PrintExtra();/调用派生类新定义的函数调用派生类新定义的函数return 0;10Number:100Name:wangAge:18Grade:1程序的运行结果为:程序的运行结果为:11图图5.5 基类与派生类中的成员基类与派生类中的成员 125.3 派生类的访问属性派生类的访

6、问属性 v类的成员可以分为类的成员可以分为public(公有)、公有)、protected(保护)和保护)和private(私有)三种访问权限私有)三种访问权限v类的继承方式有公有继承(类的继承方式有公有继承(public)、)、保护继保护继承(承(protected)和私有继承(和私有继承(private)三种三种13表表5.1不同继承方式下的访问控制权限不同继承方式下的访问控制权限基类成员的权限继承方式publicprotectedprivatepublic在派生类中为public在派生类中为protected在派生类中为privateprotected在派生类中为protected在派生

7、类中为private在派生类中为privateprivate在派生类中不可访问在派生类中不可访问在派生类中不可访问14【例【例5.2】公有继承时的访问控制权限。】公有继承时的访问控制权限。/*05_02.cpp*/#includeusing namespace std;class Base private:int a;void fun1()coutaendl;protected:int b;void fun2()coutcendl;public:int c;void fun3()coutbendl;void seta(int i)/修改私有成员修改私有成员a的值的值 a=i;int geta(

8、)/返回私有成员返回私有成员a的值的值 return a;Base(int i,int j,int k)/基类的构造函数基类的构造函数 a=i;b=j;c=k;15class Sub:public Base private:int d;public:Sub(int i,int j,int k,int m):Base(i,j,k)/派生类构造函数派生类构造函数 d=m;void test()/coutaendl;/错误,无法访问基类的私有成员错误,无法访问基类的私有成员coutb endl;/正确,可以访问基类的保护成员正确,可以访问基类的保护成员coutc endl;/正确,可以访问基类的公有

9、成员正确,可以访问基类的公有成员/fun1();/错误,无法访问基类的私有成员错误,无法访问基类的私有成员fun2();/正确,可以访问基类的保护成员正确,可以访问基类的保护成员fun3();/正确,可以访问基类的公有成员正确,可以访问基类的公有成员seta(10);/正确,间接访问基类成员正确,间接访问基类成员acout d endl;/正确,可以访问派生类的私有成员正确,可以访问派生类的私有成员;16int main()Base b1(5,6,7);/cout b1.a;/错误,无法访问对象的私有成员错误,无法访问对象的私有成员/coutb1.b;/错误,错误,无法访问对象的保护成员无法访

10、问对象的保护成员coutb1.cendl;/正确,可以访问对象的公有成员正确,可以访问对象的公有成员coutb1.geta()endl;/正确,间接访问对象的私有成员正确,间接访问对象的私有成员aSub s1(11,15,19,22);s1.test();/正确,可以访问对象的公有成员正确,可以访问对象的公有成员s1.c=200;/正确,可以访问对象的公有成员正确,可以访问对象的公有成员s1.fun3();/正确,可以访问对象的公有成员正确,可以访问对象的公有成员return 0;175.4 派生类的构造函数和析构函数派生类的构造函数和析构函数 v基类的构造函数和析构函数是不能继承基类的构造函

11、数和析构函数是不能继承v派生类的构造函数对来自基类数据成员和新增派生类的构造函数对来自基类数据成员和新增加的数据成员初始化加的数据成员初始化v执行派生类的构造函数时,需要调用基类的构执行派生类的构造函数时,需要调用基类的构造函数造函数185.4.1 派生类构造函数和析构函数的执行顺序派生类构造函数和析构函数的执行顺序 v派生类中还可用其他类的对象作为成员,又涉及到派生派生类中还可用其他类的对象作为成员,又涉及到派生类中对象成员的构造问题类中对象成员的构造问题v用派生类定义对象后,派生类对象、对象成员、基类对用派生类定义对象后,派生类对象、对象成员、基类对象的构造函数的调用顺序:象的构造函数的调

12、用顺序:基类的构造函数基类的构造函数对象成员的构造函数(如果有的话),有多个时按声明的顺序对象成员的构造函数(如果有的话),有多个时按声明的顺序派生类的构造函数派生类的构造函数19【例【例5.3】派生类构造实例。】派生类构造实例。/*05_03.cpp*/#includeusing namespace std;class Bpublic:B()cout”Construct B”endl;class Cpublic:C()cout”Construct C”endl;class D:public Bprivate:C c1;public:D()cout”Construct D”endl;int m

13、ain()D d1;return 0;20construct BConstruct CConstruct D程序的运行结果为:程序的运行结果为:21v析构函数与构造函数执行的顺相反,将按如下析构函数与构造函数执行的顺相反,将按如下顺序执行:顺序执行:(1)派生类的构造函数派生类的构造函数(2)对象成员的构造函数(如果有的话),有多个时对象成员的构造函数(如果有的话),有多个时与声明的顺序相反与声明的顺序相反(3)基类对象的析构函数基类对象的析构函数22对例对例5.3中的程序进行改造,为每一个类添加析构函数,然后再进行测试。中的程序进行改造,为每一个类添加析构函数,然后再进行测试。class B

14、public:B()cout”Construct B”endl;B()cout”Deconstruct B”endl;class Cpublic:C()cout”Construct C”endl;C()cout”Deconstruct C”endl;class D:public Bprivate:C c1;public:D()cout”Construct D”endl;D()cout”Deconstruct D”endl;int main()D d1;return 0;23Construct BConstruct CConstruct DDestruct DDestruct CDestruct

15、 B程序的运行结果为:程序的运行结果为:245.4.2 派生类构造函数和析构函数的构造规则派生类构造函数和析构函数的构造规则 v派生类中基类成员的构造,由基类构造函数完派生类中基类成员的构造,由基类构造函数完成,不能由派生类的构造函数构造成,不能由派生类的构造函数构造v派生类构造函数负责调用基类构造函数并提供派生类构造函数负责调用基类构造函数并提供基类构造函数所需的参数基类构造函数所需的参数25下面分两种情况讨论派生类对象的构造:下面分两种情况讨论派生类对象的构造:1基类定义了默认构造函数,默认构造函数能完成基类定义了默认构造函数,默认构造函数能完成派生类对象中基类成员的构造,则派生类构造函派

16、生类对象中基类成员的构造,则派生类构造函数无需显式调用基类构造函数,直接调用基类的数无需显式调用基类构造函数,直接调用基类的默认构造函数即可默认构造函数即可26【例【例5.4】分析下面程序的输出结果。】分析下面程序的输出结果。/*05_04.cpp*/#includeusing namespace std;class Basepublic:Base()a=0;Base(int i)a=i;protected:int a;class Derived:public Basepublic:Derived()b=0;Derived(int i)b=i;void Print()couta=a,b=ben

17、dl;private:int b;27int main()Derived d1;Derived d2(12);d1.Print();d2.Print();return 0;28a=0,b=0a=0,b=12程序的运行结果为:程序的运行结果为:292基类定义了有参数的构造函数,或者所定义的默基类定义了有参数的构造函数,或者所定义的默认构造函数不能完成基类成员的构造,则通过派认构造函数不能完成基类成员的构造,则通过派生类构造函数显式调用基类的构造函数,通过生类构造函数显式调用基类的构造函数,通过“成员初始化列表成员初始化列表”实现实现v派生类中普通数据成员的初始化、对象成员的构派生类中普通数据成员

18、的初始化、对象成员的构造可以放在成员初始化列表中完成造可以放在成员初始化列表中完成派生类的构造函数定义如下:派生类的构造函数定义如下:派生类名派生类名(参数列表参数列表):基类构造函数基类构造函数(参数列表参数列表1),子对象成员子对象成员1(参数列表)(参数列表)派生类构造函数体派生类构造函数体30【例【例5.5】派生类构造函数举例。】派生类构造函数举例。/*05_05.cpp*/#include#include using namespace std;class Date/日期类日期类private:int year,mon,day;/年、月、日成员变量年、月、日成员变量public:Da

19、te(int y=2009,int m=6,int d=10)/构造函数构造函数year=y;mon=m;day=d;void Print()/输出数据,格式为:年输出数据,格式为:年-月月-日日coutyear-mon-dayendl;31class Student/定义学生基类定义学生基类 protected:int number;/数据成员数据成员char name20;char sex;public:Student()/重定义的默认构造函数重定义的默认构造函数number=0;strcpy(name,No name);/默认名字默认名字sex=M;/默认性别,男性默认性别,男性(mal

20、e)dStudent(int n,char*s,char x)/带参数的构造函数带参数的构造函数number=n;strcpy(name,s);sex=x;32/大学生派生类大学生派生类class UGStudent:public Student public:UGStudent(int n,char*s,char x,int a,int y,int m,int d):Student(n,s,x),birth(y,m,d)age=a;UGStudent()/此处省略了此处省略了Student()调用调用age=0;void Print()/输出信息输出信息coutnumber:numberen

21、dl;coutname:nameendl;coutsex:sexendl;coutage:ageendl;coutbirthday:;birth.Print();private:int age;Date birth;/对象成员对象成员;33/主函数主函数int main()UGStudent st1;/用派生的默认构造函数定义对象用派生的默认构造函数定义对象UGStudent st2(1001,Zhang,F,20,2009,6,11);/带参数构造带参数构造st1.Print();st2.Print();return 0;34number:0name:No namesex:Mage:0bir

22、thday:2009-6-10number:1001name:Zhangsex:Fage:20birthday:2009-6-11程序的运行结果为:程序的运行结果为:355.5 多继承多继承 5.5.1 多继承的声明多继承的声明 v多继承下派生类的声明格式如下:多继承下派生类的声明格式如下:class 派生类名派生类名:继承方式继承方式1 基类名,继承方式基类名,继承方式2 基类名基类名2 2 派生类类体派生类类体;36如下为最基本的定义形式:如下为最基本的定义形式:class B1;class B2;class D:public B1,public B2;37图图5.6 多继承类多继承类D中

23、的成员中的成员 385.5.2 多继承的构造函数与析构函数多继承的构造函数与析构函数 v在多继承的情况下,派生类的构造函数格式如下:在多继承的情况下,派生类的构造函数格式如下:派生类名(参数列表)派生类名(参数列表):基类名基类名1(参数表参数表1),基类名基类名2(参数表参数表2),子对象名子对象名(参数表参数表n)派生类构造函数体;派生类构造函数体;39v派生类构造函数执行顺序是先执行所有基类的派生类构造函数执行顺序是先执行所有基类的构造函数,再执行派生类本身构造函数构造函数,再执行派生类本身构造函数v处于同一层次的各基类构造函数的执行顺序取处于同一层次的各基类构造函数的执行顺序取决于声明

24、派生类时所指定的各基类顺序决于声明派生类时所指定的各基类顺序v析构函数的调用顺序与构造函数完全相反析构函数的调用顺序与构造函数完全相反40【例【例5.6】多继承举例。】多继承举例。/*05_06.cpp*/#include#include using namespace std;/定义研究生基类定义研究生基类class GStudent protected:int number;/学号学号 char name20;/名字名字char sex;/性别,男性:性别,男性:M,女性:女性:Fpublic:GStudent(int n,char*s,char x)/带参数的构造函数带参数的构造函数nu

25、mber=n;strcpy(name,s);sex=x;coutConstruct GStudent.endl;GStudent()/析构函数析构函数 coutDestruct GStudent.endl;41class Employee/职员类职员类protected:char ename20;/职员名字职员名字char jobname20;/工作名工作名public:Employee(char*sn,char*sj)/构造函数构造函数strcpy(ename,sn);strcpy(jobname,sj);coutConstruct Employee.endl;Employee()/析构函数

26、析构函数 coutDestruct Employee.endl;42/在职研究生类,从两个基类派生在职研究生类,从两个基类派生class GStudentHasJob:public GStudent,public Employee public:GStudentHasJob(int n,char*s,char x,char*sj):GStudent(n,s,x),Employee(s,sj)coutConstruct GStudentHasJob.endl;GStudentHasJob()coutDestruct GStudentHasJob.endl;void Print()/输出信息输出信

27、息coutnumber:numberendl;coutname:nameendl;coutsex:sexendl;coutjob:jobnameendl;43/主函数主函数int main()/定义一个在职研究生对象,并对其初始化定义一个在职研究生对象,并对其初始化GStudentHasJob st(1001,zhang,F,teacher);st.Print();return 0;44Construct GStudent.Construct Employee.Construct GStudentHasJob.number:1001name:zhangsex:Fjob:teacherDestr

28、uct GStudentHasJob.Destruct Employee.Destruct GStudent.程序的运行结果为:程序的运行结果为:455.6 基类成员访问和赋值兼容性基类成员访问和赋值兼容性 5.6.1基类成员名的限定访问和名字覆盖基类成员名的限定访问和名字覆盖 v为避免可能出现的成员访间冲突,需要用成员为避免可能出现的成员访间冲突,需要用成员名限定的方法显式地指定要访问的成员名限定的方法显式地指定要访问的成员46【例【例5.7】成员访问冲突。】成员访问冲突。/*05_07.cpp*/#include using namespace std;class MP3Player/mp

29、3播放器类播放器类public:void Play()/播放音乐操作播放音乐操作 coutPlay mp3 music.endl;class VideoPlayer/视频播放器类视频播放器类public:void Play()/播放视频操作播放视频操作 coutPlay video.endl;/新型的新型的mp4播放器类播放器类class MP4Player:public MP3Player,public VideoPlayerpublic:/*/;47int main()MP4Player mp4;/mp4.Play();/去掉注释,本行将产生去掉注释,本行将产生Play()函数访问不明确的

30、错误函数访问不明确的错误mp4.MP3Player:Play();mp4.VideoPlayer:Play();return 0;48Play mp3 music.Play video.程序的运行结果为:程序的运行结果为:49v对于多继承,如果在不同的基类中定义了同名对于多继承,如果在不同的基类中定义了同名的成员,在派生类中要区分成员的来源,就必的成员,在派生类中要区分成员的来源,就必须使用须使用成员名限定方法成员名限定方法50【例【例5.8】多继承中成员限定法。】多继承中成员限定法。/*05_08.cpp*/#include using namespace std;class B1/基类基类

31、B1public:int m;/成员变量成员变量mB1()/构造函数构造函数 m=0;class B2/基类基类B2public:int m;/成员变量成员变量mB2()/构造函数构造函数 m=100;51class D:public B1,public B2/派生类派生类 Dpublic:void Test()/coutmendl;/此语句将引起二义性错误此语句将引起二义性错误coutB1:m=B1:mendl;/输出基类输出基类B1中的成员中的成员m的值的值coutB2:m=B2:mendl;/输出基类输出基类B2中的成员中的成员m的值的值;int main()/主函数主函数D d1;/派

32、生类对象派生类对象d1.Test();return 0;52B1:m=0B2:m=100程序的运行结果为:程序的运行结果为:535.6.2名字覆盖名字覆盖 v派生类中定义有与基类中同名的成员时,则从派生类中定义有与基类中同名的成员时,则从基类中继承得到的成员被派生类的同名成员覆基类中继承得到的成员被派生类的同名成员覆盖,派生类对基类成员的直接访问将被派生类盖,派生类对基类成员的直接访问将被派生类中该成员取代中该成员取代v为访问基类成员,必须采用成员名限定方法为访问基类成员,必须采用成员名限定方法54【例【例5.9】成员访问冲突。】成员访问冲突。/*05_09.cpp*/#include usi

33、ng namespace std;class Circle/定义圆类定义圆类 protected:float radius;/半径半径public:Circle(float r)/构造函数构造函数radius=r;float Area()/求圆面积求圆面积 return 3.14f*radius*radius;55class Cylinder:public Circle/圆柱体派生类圆柱体派生类private:float height;/高度高度public:Cylinder(float r,float h):Circle(r)/构造函数构造函数height=h;float Area()/求圆

34、柱体面积,覆盖了基类的求圆柱体面积,覆盖了基类的Area()函数函数float botarea=0,sidearea=0;botarea=Circle:Area()*2;/底面积底面积*2sidearea=2*3.14f*radius*height;/侧面积侧面积return botarea+sidearea;float Volume()/圆柱体积圆柱体积return Circle:Area()*height;/基类求面积乘高度基类求面积乘高度;56int main()Cylinder cr1(10,5);/定义圆柱体对象定义圆柱体对象coutBottomArea=cr1.Circle:Are

35、a()endl;/访问基类成员访问基类成员coutArea=cr1.Area()endl;/访问派生类成员访问派生类成员coutVolume=cr1.Volume()endl;return 0;57BottomArea=314Area=942Volume=1570程序的运行结果为:程序的运行结果为:58v在派生类如果定义了和基类中同名的函数,则在派生类如果定义了和基类中同名的函数,则基类中所有的同名的重载函数都将被覆盖,即基类中所有的同名的重载函数都将被覆盖,即在派生类中或通过派生类对象都无法直接访问在派生类中或通过派生类对象都无法直接访问基类的任何一个同名函数基类的任何一个同名函数59图图5

36、.7 派生类对基类的名字覆盖派生类对基类的名字覆盖 605.6.3赋值兼容规则赋值兼容规则 v派生类对象和基类对象之间赋值存在赋值的方派生类对象和基类对象之间赋值存在赋值的方向,赋值兼容规则包括:向,赋值兼容规则包括:(1)基类对象可以赋值给基类对象,也可以把派生)基类对象可以赋值给基类对象,也可以把派生类对象赋值给基类对象类对象赋值给基类对象(2)基类指针可以指向基类对象,也可以指向派生)基类指针可以指向基类对象,也可以指向派生类对象类对象(3)基类引用可以指向基类对象,也可以指向派生)基类引用可以指向基类对象,也可以指向派生类对象类对象61v例如,有基类例如,有基类Base和其派生类和其派

37、生类Derived,可以定义相应可以定义相应的对象、指针:的对象、指针:Base b1;Base*pb;Derived d1;(1)派生类对象可以赋值给基类对象)派生类对象可以赋值给基类对象b1=d1;(2)派生类的对象初始化基类对象的引用派生类的对象初始化基类对象的引用Base&rb=d1;(3)基类的指针赋值为派生类对象的地址基类的指针赋值为派生类对象的地址pb=&d1;62【例【例5.10】赋值兼容实例。赋值兼容实例。/*05_10.cpp*/#includeusing namespace std;class Base/基类基类Baseprotected:int member;publi

38、c:Base()member=0;void Show()/共有成员函数共有成员函数 coutBase:Show():memberendl;class Derived1:public Base/第第1个派生类个派生类Derived1public:Derived1(int a)member=a;void Show()/重写共有成员函数重写共有成员函数Show coutDerived1:Show():memberendl;63class Derived2:public Derived1 /第第2个派生类个派生类Derived2public:Derived2(int a):Derived1(a)voi

39、d Show()/重写共有成员函数重写共有成员函数Show coutDerived2:Show():memberShow();void Test(Base&br)/测试函数,用基类引用作参数测试函数,用基类引用作参数 br.Show();int main()/主函数主函数Base b0;/基类基类Base对象对象Derived1 d1(5);/派生类派生类Derived1的对象的对象Derived2 d2(10);/派生类派生类Derived2的对象的对象Base*pb0;/基类指针基类指针pb0pb0=&b0;/基类指针基类指针pb0指向基类对象指向基类对象b0Test(pb0);b0=d1

40、;/基类对象赋值为子类对象基类对象赋值为子类对象Test(pb0);/测试输出测试输出pb0=&d1;/基类指针基类指针pb0指向基第一派生类指向基第一派生类Derived1的对象的对象d1Test(pb0);Test(d2);/第第2派生类派生类Derived2的对象的对象d2的引用作参数传给的引用作参数传给Test函数函数return 0;64Base:Show():0Base:Show():5Base:Show():5Base:Show():10程序的运行结果为:程序的运行结果为:655.6 虚基类虚基类 5.6.1 提出问题提出问题 v在多继承关系中,派生类在多继承关系中,派生类D0的

41、多个基类(类的多个基类(类Bl 和和B2)派生自另一个公共基类派生自另一个公共基类B0,则在派生类则在派生类对象中,会通过不同的继承路径多次得到基类对象中,会通过不同的继承路径多次得到基类B0 的成员,即同时存在多份基类的成员,即同时存在多份基类B0 的成员。的成员。v派生类对象中存在基类成员的多个副本派生类对象中存在基类成员的多个副本66图图5.8 多继承关系及派生类的成员构成多继承关系及派生类的成员构成UML图图 675.6.2 虚基类的概念虚基类的概念 v为使得公共基类为使得公共基类B0在派生类在派生类D0中只产生一份基类成员,中只产生一份基类成员,则需要将共同基类则需要将共同基类B0

42、设置为设置为虚基类虚基类v让基类让基类Bl和和B2从基类从基类B0虚拟继承,这时从不同的路径继虚拟继承,这时从不同的路径继承过来的同名数据成员在派生类中只有一个副本承过来的同名数据成员在派生类中只有一个副本v使用虚基类,可以使公共基类的成员在其间接派生类中使用虚基类,可以使公共基类的成员在其间接派生类中只保留一份只保留一份68图图5.9 虚基类多继承关系及派生类的成员构成虚基类多继承关系及派生类的成员构成UML图图 69v定义虚基类的格式如下:定义虚基类的格式如下:class 派生类名:派生类名:virtual 继承方式继承方式 基类名称基类名称;70在图在图5.9中的几个类可以写成如下形式:

43、中的几个类可以写成如下形式:class B0public:int nv0;class B1:virtual public B0public:int nv1;class B2:virtual public B0public:int nv2;class D0:public B1,public B2public:int nv3;715.6.3 虚基类的初始化虚基类的初始化 关于虚基类的初始化,有如下两条规则:关于虚基类的初始化,有如下两条规则:(1)所有从虚基类派生的类必须在该类构造函数的成员初)所有从虚基类派生的类必须在该类构造函数的成员初始化列表列出对虚基类构造函数的调用,只有实际构造始化列表列

44、出对虚基类构造函数的调用,只有实际构造对象的类的构造函数才会引发对虚基类构造函数的调用对象的类的构造函数才会引发对虚基类构造函数的调用(2)某类构造函数的成员初始化列表中同时列出对虚基类)某类构造函数的成员初始化列表中同时列出对虚基类构造函数和非虚基类构造函数的调用,优先执行虚基类构造函数和非虚基类构造函数的调用,优先执行虚基类的构造函数的构造函数 72【例【例5.11】设置虚基类以解决二义性设置虚基类以解决二义性/*05-11.cpp*/#include using namespace std;class Base/虚基类虚基类Basepublic:Base(int a)/构造函数构造函数

45、val=a;void Print()/输出成员输出成员val值得函数值得函数 coutvalendl;protected:int val;/成员变量成员变量val;class Derived1:virtual public Base/第一个派生类第一个派生类Derived1public:Derived1(int x,int y):Base(x),dv1(y)/调用了基类的构造函数调用了基类的构造函数protected:int dv1;73class Derived2:virtual public Basepublic:Derived2(int x,int y):Base(x),dv2(y)/调

46、用了基类的构造函数调用了基类的构造函数protected:int dv2;/最终的多重继承类最终的多重继承类DerivedFinalclass DerivedFinal:public Derived1,public Derived2public:DerivedFinal(int x,int y,int z):Derived1(x,y),Derived2(y,z),Base(z);int main()DerivedFinal df(7,18,22);/定义对象定义对象df.Print();/输出虚基类输出虚基类Base的成员的成员val的值的值return 0;74 22 程序的运行结果为:程序的运行结果为:

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

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(第5章-继承与派生课件.ppt)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|