第8章+类的继承与多态性_第1页
第8章+类的继承与多态性_第2页
第8章+类的继承与多态性_第3页
第8章+类的继承与多态性_第4页
第8章+类的继承与多态性_第5页
已阅读5页,还剩113页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、高级语言程序设计高级语言程序设计C+张海威张海威南开大学计算机与控制工程学院南开大学计算机与控制工程学院http:/第第8 8章章 类的继承与多态性类的继承与多态性类的继承与派生类的继承与派生1派生类派生类2虚基类虚基类3类的多态性与虚函数类的多态性与虚函数42Database & Information System Lab综合示例综合示例5http:/第第8 8章章 类的继承与多态性类的继承与多态性类的继承与派生类的继承与派生1派生类派生类2虚基类虚基类3类的多态性与虚函数类的多态性与虚函数43Database & Information System Lab综合示例综合示

2、例5http:/类的继承与派生类的继承与派生vC+C+程序用不同的类定义来表示一组数据以程序用不同的类定义来表示一组数据以及对这些数据的操作与处理,而类之间往及对这些数据的操作与处理,而类之间往往具有某种关系,往具有某种关系,“继承与派生继承与派生”就是类就是类间的一种常用关系。间的一种常用关系。 例如,交通工具例如,交通工具汽车汽车轿车轿车红旗轿车红旗轿车具有层次关系!具有层次关系! 汽车汽车 是一种特殊的是一种特殊的 交通工具交通工具 轿车轿车是一种特殊的是一种特殊的 汽车汽车 红旗轿车红旗轿车是一种特殊的是一种特殊的 轿车轿车Database & Information Syst

3、em Lab4http:/类的继承与派生类的继承与派生v继承继承(inheritance)(inheritance)与派生与派生 该机制是面向对象程序设计使代码可以复用的该机制是面向对象程序设计使代码可以复用的最重要的手段最重要的手段 它允许程序员在保持原有类特性的基础上进行它允许程序员在保持原有类特性的基础上进行扩展,增加功能扩展,增加功能 继承产生新的类,称为继承产生新的类,称为派生类派生类 派生类可以访问基类的保护成员(在基类中以关键派生类可以访问基类的保护成员(在基类中以关键字字protected标识的成员)标识的成员) 继承呈现了面向对象程序设计的层次结构,体继承呈现了面向对象程序设

4、计的层次结构,体现了由简单到复杂的认识过程现了由简单到复杂的认识过程Database & Information System Lab5http:/类的继承与派生类的继承与派生v层次概念层次概念是计算机的重要概念。通过是计算机的重要概念。通过继承继承(inheritanceinheritance)的机制可对类()的机制可对类(classclass)分层,提供类型分层,提供类型/ /子类型的关系。子类型的关系。vC+C+通过通过类派生类派生(class derivationclass derivation)的机)的机制来支持继承。被继承的类称为制来支持继承。被继承的类称为基类基类(bas

5、e classbase class)或)或超类超类(superclasssuperclass),),新的类为新的类为派生类派生类(derived classderived class)或)或子类子类(subclasssubclass)。基类和派生类的集合称作)。基类和派生类的集合称作类继承层次结构类继承层次结构(hierarchyhierarchy)Database & Information System Lab6http:/类的继承与派生类的继承与派生v如果基类和派生类共享相同的公有接口,如果基类和派生类共享相同的公有接口,则派生类被称作基类的则派生类被称作基类的子类型子类型(su

6、btypesubtype)v派生反映了事物之间的联系,事物的派生反映了事物之间的联系,事物的共性共性与个性与个性之间的关系之间的关系v派生与独立设计若干相关的类,前者工作派生与独立设计若干相关的类,前者工作量少,重复的部分可以从基类继承来,不量少,重复的部分可以从基类继承来,不需要单独编程。需要单独编程。 Database & Information System Lab7http:/类的继承与派生类的继承与派生v【例如例如】公司四种雇员档案的管理:公司四种雇员档案的管理: employeeemployee(雇员)雇员) 姓名、年龄、工资;姓名、年龄、工资; managermanage

7、r(经理)经理) 姓名、年龄、工资、姓名、年龄、工资、行政级别行政级别; engineerengineer(工程师)工程师) 姓名、年龄、工资、姓名、年龄、工资、专业、学位专业、学位; directordirector(高级主管)高级主管) 姓名、年龄、工资、姓名、年龄、工资、行政级别、职务行政级别、职务。Database & Information System Lab8http:/类的继承与派生类的继承与派生v【例例8.18.1】假设公司雇员分为:雇员假设公司雇员分为:雇员( (employee)employee)、经理经理( (manager)manager)、工程师工程师( (

8、engineer)engineer)、高级主管高级主管( (director)director)。且假定且假定只关心这几类雇员各自的如下一些数据:只关心这几类雇员各自的如下一些数据: employee(employee(雇员雇员) )类:姓名、年龄、工资;类:姓名、年龄、工资; manager(manager(经理经理) )类:姓名、年龄、工资、行政级别;类:姓名、年龄、工资、行政级别; engineer(engineer(工程师工程师) )类姓名、年龄、工资、专业、学位;类姓名、年龄、工资、专业、学位; director(director(高级主管高级主管) )类:姓名、年龄、工资、行政级类

9、:姓名、年龄、工资、行政级别、职务。别、职务。Database & Information System Lab9http:/类的继承与派生类的继承与派生#include #include using namespace std;class employee/employee类将作为其它几个类的基类类将作为其它几个类的基类 short age; float salary; protected: char * name;public: employee(short ag,float sa,char * na) age=ag;salary=sa;name=new charstrlen(na

10、)+1;strcpy(name,na);Database & Information System Lab10http:/类的继承与派生类的继承与派生void print ()cout name: ;coutage : ;coutsalaryendl; employee() deletename; ; Database & Information System Lab11http:/类的继承与派生类的继承与派生class manager:public employee /派生类派生类int level;public:manager(short ag, float sa, cha

11、r* na, int lev):employee (ag,sa,na) /对基类初始化负责对基类初始化负责level=lev; void print() employee:print();/调用基类调用基类print显示显示“共性共性”数据数据cout level:levelendl; ;Database & Information System Lab12http:/类的继承与派生类的继承与派生/*注意:允许派生类中的注意:允许派生类中的print与基类的与基类的print重名,按重名,按如下规定进行处理:对子类而言,不加类名限定时默认如下规定进行处理:对子类而言,不加类名限定时默认

12、为是处理子类成员,而要访问父类重名成员时,则要通为是处理子类成员,而要访问父类重名成员时,则要通过类名限定过类名限定*/class engineer:public employee char speciality,adegree; public: .;enum ptitle PS,GM,VPS,VGM;class director:public manager ptitle post; public: .;Database & Information System Lab13http:/类的继承与派生类的继承与派生void main() /主函数主函数employee emp1(23,

13、610.5,zhang), emp2(27,824.75,zhao);manager man1(32,812.45,li,11), man2(34,1200.5,cui,7);engineer eng(26,1420.10,meng,E,M);director dir(38,1800.2,zhou,2,GM);emp1.print();emp2.print();man1.print();man2.employee:print(); /调用基类的调用基类的print eng.print();dir.print();Database & Information System Lab14ht

14、tp:/类的继承与派生类的继承与派生程序执行后的显示结果如下:程序执行后的显示结果如下:zhang: 23 : 610.5zhao: 27 : 824.75li: 32 : 812.45level:11cui: 34 : 1200.5meng: 26 : 1420.1speciality:Eacademic degree:Mzhou: 38 : 1800.2level:2post:1Database & Information System Lab15http:/类的继承与派生类的继承与派生v单继承单继承 派生类只有一个直接基类的情况称为单继承派生类只有一个直接基类的情况称为单继承(s

15、ingle-inheritancesingle-inheritance)。)。Database & Information System Lab16基类基类派生类派生类1 1派生类派生类2 2一个基类可以一个基类可以直接派生出多直接派生出多个派生类个派生类 http:/类的继承与派生类的继承与派生v多重继承多重继承 如果一个派生类可以同时有多个基类,称为多如果一个派生类可以同时有多个基类,称为多重继承(重继承(multiple-inheritancemultiple-inheritance),这时的派),这时的派生类同时得到了多个已有类的特征。生类同时得到了多个已有类的特征。Datab

16、ase & Information System Lab17基类基类1 1基类基类2 2基类基类n n派生类派生类1 1派生类派生类2 2派生类可以由派生类可以由多个基类共同多个基类共同派生出来,派生出来,称称为为多重多重继承继承。http:/类的继承与派生类的继承与派生v多层次继承多层次继承 在派生过程中,派生出来的新类同样可以作为在派生过程中,派生出来的新类同样可以作为基类再继续派生出更新的类,依此类推形成一基类再继续派生出更新的类,依此类推形成一个层次结构。直接参与派生出某类称为直接基个层次结构。直接参与派生出某类称为直接基类,而基类的基类,以及更深层的基类称为类,而基类的基类,

17、以及更深层的基类称为间间接基类接基类。v类族类族 同时一个基类可以直接派生出多个派生类。这同时一个基类可以直接派生出多个派生类。这样形成了一个相互关联的样形成了一个相互关联的类族类族。如。如MFCMFC就是这就是这样的族类,它由一个样的族类,它由一个CObjectCObject类派生出类派生出200200个个MFCMFC类中的绝大多数。类中的绝大多数。Database & Information System Lab18http:/类的继承与派生类的继承与派生v派生编程的步骤派生编程的步骤Database & Information System Lab19编制编制派生派生类时

18、类时可分可分四步四步 吸收基类的成员吸收基类的成员 改造基类成员改造基类成员 发展新成员发展新成员 重写构造函数与析构函数重写构造函数与析构函数 不论是数据成员,还是函数不论是数据成员,还是函数成员成员(非私有成员),(非私有成员),除构造函数与析除构造函数与析构函数外全盘接收构函数外全盘接收 声明一个和某基类成员同名的新声明一个和某基类成员同名的新成员成员, ,派生类中的新成员就屏蔽了派生类中的新成员就屏蔽了基类同名成员称为同名覆盖基类同名成员称为同名覆盖(overrideoverride) 派生类新成员必须与基类成员派生类新成员必须与基类成员不同名,它的加入保证派生类不同名,它的加入保证派

19、生类在功能上有所发展。在功能上有所发展。 http:/类的继承与派生类的继承与派生v派生编程的步骤派生编程的步骤 第二步中,第二步中,新成员如是成员函数,参数表也必新成员如是成员函数,参数表也必须一样须一样,否则是重载。,否则是重载。 第三步中,独有的新成员才是继承与派生的核第三步中,独有的新成员才是继承与派生的核心特征。心特征。 第四步是重写构造函数与析构函数,派生类不第四步是重写构造函数与析构函数,派生类不继承这两种函数。不管原来的函数是否可用继承这两种函数。不管原来的函数是否可用一一律重写律重写可免出错。可免出错。Database & Information System Lab

20、20http:/第第8 8章章 类的继承与多态性类的继承与多态性类的继承与派生类的继承与派生1派生类派生类2虚基类虚基类3类的多态性与虚函数类的多态性与虚函数421Database & Information System Lab综合示例综合示例5http:/派生类派生类派生类派生类派生类的访问权限派生类的访问权限派生类的定义派生类的定义友元与友元与静态成员的继承静态成员的继承二义性问题二义性问题派生类对象的派生类对象的说明与初始化说明与初始化赋值兼容性问题赋值兼容性问题22Database & Information System Labhttp:/派生类的定义派生类的定义c

21、lass : private: ;public: ;protected: ; 的一般格式为:的一般格式为: ,. , 又可为又可为private、 public或或protected Database & Information System Lab23http:/派生类的访问权限派生类的访问权限派生方式派生方式( (基类基类 在基类中的在基类中的 在派生类中在派生类中 的被继承方式的被继承方式) ) 存取权限存取权限 的存取权限的存取权限=publicpublicpublicpublicpublicpublicpublicpublicpotectedpotected protecte

22、dprotectedpublicpublicprivateprivate(inaccessible)(inaccessible)potected potected publicpublicprotectedprotectedpotectedpotectedpotectedpotected protectedprotectedpotectedpotectedprivateprivate(inaccessible)(inaccessible)privateprivatepublicpublicprivateprivateprivateprivatepotectedpotected privatep

23、rivateprivateprivateprivateprivate(inaccessible)(inaccessible) =Database & Information System Lab24http:/派生类的访问权限派生类的访问权限vpublicpublic派生方式派生方式 使基类的公有成员和保护成员在派生类中仍然使基类的公有成员和保护成员在派生类中仍然是公有成员和保护成员,而基类的私有成员不是公有成员和保护成员,而基类的私有成员不可在派生类中被存取。可在派生类中被存取。vprotectedprotected派生方式派生方式 使基类的公有成员和保护成员在派生类中都变使基类的公

24、有成员和保护成员在派生类中都变为保护成员,而基类的私有成员不可在派生类为保护成员,而基类的私有成员不可在派生类中被存取。中被存取。vprivateprivate派生方式派生方式 使基类的公有成员和保护成员在派生类中都变使基类的公有成员和保护成员在派生类中都变为私有成员,而基类的私有成员不可在派生类为私有成员,而基类的私有成员不可在派生类中被存取。中被存取。Database & Information System Lab25http:/派生类的访问权限派生类的访问权限v派生类的成员可根据访问权限分为四类派生类的成员可根据访问权限分为四类 不可访问的成员不可访问的成员 基类的基类的pri

25、vateprivate私有成员被继承过来后,这些成员私有成员被继承过来后,这些成员在派生类中是不可访问的。在派生类中是不可访问的。 私有成员私有成员 包括在派生类中新增加的包括在派生类中新增加的privateprivate私有成员以及从私有成员以及从基类私有继承过来的某些成员。这些成员在派生类基类私有继承过来的某些成员。这些成员在派生类中是可以访问的。中是可以访问的。Database & Information System Lab26http:/派生类的访问权限派生类的访问权限v派生类的成员可根据访问权限分为四类派生类的成员可根据访问权限分为四类 保护成员保护成员 包括在派生类中新增

26、加的包括在派生类中新增加的protectedprotected保护成员以及保护成员以及从基类继承过来的某些成员。这些成员在派生类中从基类继承过来的某些成员。这些成员在派生类中是可以访问的。是可以访问的。 公有成员公有成员 包括在派生类中新增加的包括在派生类中新增加的publicpublic公有成员以及从基公有成员以及从基类公有继承过来的基类的类公有继承过来的基类的publicpublic成员。这些成员不成员。这些成员不仅在派生类中可以访问,而且在建立派生类对象的仅在派生类中可以访问,而且在建立派生类对象的模块中,也可以通过对象来访问它们模块中,也可以通过对象来访问它们Database &

27、; Information System Lab27http:/派生类的访问权限派生类的访问权限v【例例8.28.2】读程序,分析运行结果读程序,分析运行结果class baseCla int privData; protected: int protData; public: int publData; ;class publDrvCla : public baseCla public:void usebaseClaData() publData=11; /OK!protData=12; /OK!privData=13; /ERROR! ;Database & Information

28、 System Lab28http:/派生类的访问权限派生类的访问权限class claD21 : public publDrvCla public:void usebaseClaData() publData=111; /OK!protData=121; /OK!privData=131; /ERROR! ;class protDrvCla : protected baseCla public:void usebaseClaData() publData=21; /OK!protData=22; /OK!privData=23; /ERROR! ;Database & Informa

29、tion System Lab29http:/派生类的访问权限派生类的访问权限class claD22 : public protDrvCla public:void usebaseClaData() publData=211; /OK!protData=221; /OK!privData=231; /ERROR! ;class claD22 : public protDrvCla public:void usebaseClaData() publData=211; /OK!protData=221; /OK!privData=231; /ERROR! ;Database & Info

30、rmation System Lab30http:/派生类的访问权限派生类的访问权限class privDrvCla : private baseCla public:void usebaseClaData() publData=31; /OK!protData=32; /OK! privData=33; /ERROR! ;class claD23 : public privDrvCla public:void usebaseClaData() publData=311; /ERROR!protData=321; /ERROR!privData=331; /ERROR! ;Database &

31、amp; Information System Lab31http:/派生类的访问权限派生类的访问权限void main() baseCla ob0;ob0.publData=1; /OK! tData=2; /ERROR!ob0.privData=3; /ERROR!claD21 d21;claD22 d22;claD23 d23;d21.publData=4; /OK!tData=5; /ERROR! d21.privData=6; /ERROR! d22.publData=7; /ERROR! tData=8; /ERROR!d22.privDa

32、ta=9; /ERROR! d23.publData=7; /ERROR!tData=8; /ERROR! d23.privData=9; /ERROR!Database & Information System Lab32http:/派生类对象的说明派生类对象的说明v派生类对象的说明与所有类对象的说明方派生类对象的说明与所有类对象的说明方式相同式相同 ,nv类对象进行说明的同时,需要进行初始化类对象进行说明的同时,需要进行初始化 初始化列表初始化列表 派生类的构造函数派生类的构造函数Database & Information System Lab33http:

33、/派生类的构造函数派生类的构造函数v派生类的构造函数的一般格式如下:派生类的构造函数的一般格式如下:(): 按如下格式构成:按如下格式构成: ()1), . . , ()n), ()1), . . , ()m)若若无对象成员无对象成员时,则不出现此后半部分;基类名与时,则不出现此后半部分;基类名与对象成员名的次序无关紧要,各自出现的顺序可以对象成员名的次序无关紧要,各自出现的顺序可以任意任意Database & Information System Lab34http:/派生类的构造函数派生类的构造函数v派生类构造函数执行的一般次序如下:派生类构造函数执行的一般次序如下: 调用各基类的

34、构造函数,调用顺序为派生继承调用各基类的构造函数,调用顺序为派生继承时的时的基类声明顺序基类声明顺序。 若派生类含有对象成员的话,调用各对象成员若派生类含有对象成员的话,调用各对象成员的构造函数,调用顺序按照派生类中的构造函数,调用顺序按照派生类中对象成员对象成员的声明顺序的声明顺序。 执行派生类构造函数的函数体。执行派生类构造函数的函数体。Database & Information System Lab35http:/派生类的构造函数派生类的构造函数v派生类构造函数与基类构造函数的联系派生类构造函数与基类构造函数的联系 在派生类构造函数中,只要基类不是使用无参在派生类构造函数中,只

35、要基类不是使用无参的默认构造函数都要显式给出基类名和参数表。的默认构造函数都要显式给出基类名和参数表。 如果如果基类没有定义构造函数,则派生类也可以基类没有定义构造函数,则派生类也可以不定义,全部采用系统给定的默认构造函数。不定义,全部采用系统给定的默认构造函数。 如果基类定义了带有形参表的构造函数时,派如果基类定义了带有形参表的构造函数时,派生类就应当定义构造函数。生类就应当定义构造函数。Database & Information System Lab36http:/派生类的析构函数派生类的析构函数v析构函数析构函数的功能是作善后工作。的功能是作善后工作。 只要在函数体内把派生类新

36、增的一般成员处理只要在函数体内把派生类新增的一般成员处理好就可以了好就可以了,而对新增的成员对象和基类的善,而对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析后工作,系统会自己调用成员对象和基类的析构函数来完成。构函数来完成。v析构函数各部分执行次序与构造函数相反析构函数各部分执行次序与构造函数相反 首先对派生类新增一般成员析构,然后对新增首先对派生类新增一般成员析构,然后对新增对象成员析构,最后对基类成员析构对象成员析构,最后对基类成员析构Database & Information System Lab37http:/派生类的说明与初始化派生类的说明与初始化v【例

37、例8.38.3】读程序,分析运行结果读程序,分析运行结果#includeusing namespace std;class CBint b;public:CB(int n)b=n; coutCB:b=bendl; ;CB()coutCBobj is destructingendl; class CC int c;public:CC(int n1,int n2) c=n1; coutCC:c=cendl; ;CC()coutCCobj is destructingendl;Database & Information System Lab38http:/派生类的说明与初始化派生类的说明与

38、初始化class CD:public CB,public CC int d;public: CD(int n1,int n2,int n3,int n4) :CC(n3,n4),CB(n2)/先先CB,后后CC d=n1; coutCD:d=dendl; CD()coutCDobj is destructingendl; ;void main(void) CD CDobj(2,4,6,8);Database & Information System Lab39http:/派生类的说明与初始化派生类的说明与初始化运行结果为:运行结果为:CB:b=4CC:c=6CD:d=2CDobj is

39、 destructingCCobj is destructingCBobj is destrcting 【思考思考】将派生类将派生类CDCD改写为如下形式后,请给出输改写为如下形式后,请给出输出结果。出结果。 Database & Information System Lab40http:/派生类的说明与初始化派生类的说明与初始化class CD:public CB,public CC int d; CC obcc; CB obcb;public: CD(int n1,int n2,int n3,int n4) :CC(n3,n4), CB(n2), obcb(100+n2), obc

40、c(100+n3,100+n4) d=n1; coutCD:d=dendl; ; CD()coutCDobj is destructingendl;Database & Information System Lab41/先基类先基类CB、CC,再对象成员,再对象成员CC、CB,最后派生类,最后派生类CDhttp:/派生类的说明与初始化派生类的说明与初始化输出结果:输出结果:CB:b=4CC:c=6CC:c=106CB:b=104CD:d=2CDobj is destructingCBobj is destructingCCobj is destructingCCobj is destr

41、uctingCBobj is destructingDatabase & Information System Lab42http:/友元的继承友元的继承v基类的友元不继承基类的友元不继承 如果基类有友元类或友元函数,则其派生类不如果基类有友元类或友元函数,则其派生类不因继承关系也有此友元类或友元函数。因继承关系也有此友元类或友元函数。v如果基类是某类的友元,则这种友元关系如果基类是某类的友元,则这种友元关系是是被继承被继承的。即,被派生类继承过来的成的。即,被派生类继承过来的成员,如果原来是某类的友元,那么它作为员,如果原来是某类的友元,那么它作为派生类的成员仍然是某类的友元。总之:

42、派生类的成员仍然是某类的友元。总之: 基类的友元不一定是派生类的友元;基类的友元不一定是派生类的友元; 基类的成员是某类的友元,则其作为派生类继基类的成员是某类的友元,则其作为派生类继承的成员仍是某类的友元。承的成员仍是某类的友元。Database & Information System Lab43http:/静态成员的继承静态成员的继承v如果基类中被派生类继承的成员是静态成如果基类中被派生类继承的成员是静态成员,则其静态属性也随静态成员被继承。员,则其静态属性也随静态成员被继承。v如果基类的静态成员是公有的或是保护的,如果基类的静态成员是公有的或是保护的,则它们被其派生类继承为派生

43、类的静态成则它们被其派生类继承为派生类的静态成员。即:员。即: 这些成员通常用这些成员通常用“:”方式方式引用或调用。引用或调用。 这些成员无论有多少个对象被创建,都只有一这些成员无论有多少个对象被创建,都只有一个拷贝。它为基类和派生类的所有对象所共享。个拷贝。它为基类和派生类的所有对象所共享。 Database & Information System Lab44http:/赋值兼容性问题赋值兼容性问题v派生类对象间的赋值操作依据下面的原则:派生类对象间的赋值操作依据下面的原则: 如果派生类有自己的赋值运算符的重载定义,如果派生类有自己的赋值运算符的重载定义,即按重载后的运算符含义处

44、理。即按重载后的运算符含义处理。 派生类未定义自己的赋值操作,而基类定义了派生类未定义自己的赋值操作,而基类定义了赋值操作,则系统自动定义派生类赋值操作,赋值操作,则系统自动定义派生类赋值操作,其中基类成员的赋值按基类的赋值操作进行。其中基类成员的赋值按基类的赋值操作进行。 二者都未定义专门的赋值操作,系统自动定义二者都未定义专门的赋值操作,系统自动定义缺省赋值操作(按位进行拷贝)。缺省赋值操作(按位进行拷贝)。Database & Information System Lab45http:/赋值兼容性问题赋值兼容性问题v基类对象和派生类对象之间允许有下述的基类对象和派生类对象之间允许

45、有下述的赋值关系(赋值关系(允许将派生类对象允许将派生类对象“当作当作”基基类对象来使用类对象来使用):): 基类对象基类对象 = = 派生类对象;派生类对象; 只赋只赋“共性成员共性成员”部分部分 ,反方向的赋值,反方向的赋值“派生类派生类对象对象 = = 基类对象基类对象”不被允许不被允许 指向基类对象的指针指向基类对象的指针 = = 派生类对象的地址;派生类对象的地址; 下述赋值不允许:指向派生类类型的指针下述赋值不允许:指向派生类类型的指针 = = 基类基类对象的地址。注:访问非基类成员部分时,要经过对象的地址。注:访问非基类成员部分时,要经过指针类型的强制转换指针类型的强制转换 基类

46、的引用基类的引用 = = 派生类对象;派生类对象; 下述赋值不允许:派生类的引用下述赋值不允许:派生类的引用 = = 基类对象。基类对象。 通过引用只可以访问基类成员部分通过引用只可以访问基类成员部分Database & Information System Lab46http:/赋值兼容性问题赋值兼容性问题v【例例8.48.4】读程序,分析运行结果读程序,分析运行结果#includeusing namespace std;class base /基类基类base int a;public: base (int sa) a=sa; int geta()return a; ; class

47、 derived:public base /派生类派生类derived int b; public: derived(int sa, int sb):base(sa) b=sb; int getb()return b; ;Database & Information System Lab47http:/赋值兼容性问题赋值兼容性问题void main () base bs1(123); / base 类对象类对象bs1coutbs1.geta()=bs1.geta()endl; derived der(246,468);/ derived 类对象类对象derbs1=der; /OK! “

48、基类对象基类对象 = 派生类对象派生类对象;”coutbs1.geta()=bs1.geta()endl; /der=bs1; /ERROR! “派生类对象派生类对象 = 基类对象基类对象;”Database & Information System Lab48http:/赋值兼容性问题赋值兼容性问题base *pb = &der;/“指向基类型的指针指向基类型的指针 = 派生类对象的地址派生类对象的地址;” coutgeta()=geta()endl; /访问基类成员部分访问基类成员部分/coutgetb()endl; /ERROR! 直接访问非基类成员部分直接访问非基类成员

49、部分coutgetb()=getb()geta()=246(derived *)pb)-getb()=468 Database & Information System Lab50http:/二义性问题二义性问题v单继承时父类与子类间重名成员的处理单继承时父类与子类间重名成员的处理 单继承时父类与子类间成员重名时,按如下规单继承时父类与子类间成员重名时,按如下规定进行处理:对子类而言,不加类名限定时默定进行处理:对子类而言,不加类名限定时默认为是处理子类成员,而要访问父类重名成员认为是处理子类成员,而要访问父类重名成员时,则要通过类名限定。时,则要通过类名限定。 【例例8.58.5】读

50、程序,分析运行结果读程序,分析运行结果#include using namespace std;class CB public:int a;CB(int x)a=x;void showa()coutClass CB - a=aendl; Database & Information System Lab51http:/二义性问题二义性问题class CD:public CB public:int a; /与基类与基类a同名同名CD(int x, int y):CB(x)a=y; void showa()/与基类与基类showa同名同名coutClass CD - a=aendl;voi

51、d print2a() couta=aendl; /子类子类acoutCB:a=CB:aendl; /父类父类a; Database & Information System Lab52http:/二义性问题二义性问题void main() CB CBobj(12);CBobj.showa();CD CDobj(48, 999);CDobj.showa();/子类的子类的showaCDobj.CB:showa(); /父类的父类的showa coutCDobj.a=CDobj.aendl;coutCDobj.CB:a=CDobj.CB:aendl; 程序执行后的显示结果如下:程序执行后

52、的显示结果如下:Class CB - a=12Class CD - a=999Class CB - a=48CDobj.a=999CDobj.CB:a=48Database & Information System Lab53http:/二义性问题二义性问题v多继承情况下二基类间重名成员的处理多继承情况下二基类间重名成员的处理 多继承情况下二基类间成员重名时,按如下方多继承情况下二基类间成员重名时,按如下方式进行处理:对子类而言,不加类名限定时默式进行处理:对子类而言,不加类名限定时默认为是处理子类成员,而要访问父类重名成员认为是处理子类成员,而要访问父类重名成员时,则要通过类名限定。

53、时,则要通过类名限定。 【例例8.68.6】读程序,分析运行结果读程序,分析运行结果#include using namespace std;class CB1 public:int a; CB1(int x)a=x;void showa()cout a=aendl; Database & Information System Lab54http:/二义性问题二义性问题class CB2 public:int a; CB2(int x)a=x;void showa()cout a=aendl;class CD:public CB1, public CB2 public:int a; /

54、与二基类数据成员与二基类数据成员a同名同名CD(int x, int y, int z): CB1(x), CB2(y) a=z;Database & Information System Lab55http:/二义性问题二义性问题void showa() /与二基类成员函数与二基类成员函数showa同名同名 cout a=aendl;void print3a() /显示出派生类的显示出派生类的a及其二父类的重名成员及其二父类的重名成员acouta=aendl; coutCB1:a=CB1:aendl;coutCB2:a=CB2:aendl;Database & Informa

55、tion System Lab56http:/二义性问题二义性问题void main() CB1 CB1obj(11);CB1obj.showa();CD CDobj(101, 202,909);CDobj.showa();/子类子类showaCDobj.CB1:showa();/父类父类showacoutCDobj.a=CDobj.aendl;coutCDobj.CB2:a=CDobj.CB2:a a=11Class CD = a=909Class CB1 = a=101CDobj.a=909CDobj.CB2:a=202Database & Information System L

56、ab57http:/二义性问题二义性问题v多级混合继承多级混合继承( (非虚拟继承非虚拟继承) )包含两个基类包含两个基类实例情况的处理实例情况的处理 多级混合继承情况下,若类多级混合继承情况下,若类D D从两条不同从两条不同“路路径径”同时对类同时对类A A进行了一般性继承(非虚拟继进行了一般性继承(非虚拟继承)的话,则类承)的话,则类D D的对象中会同时包含着两个的对象中会同时包含着两个类类A A的实例。此时,对类的实例。此时,对类D D而言,要通过类名限而言,要通过类名限定来指定访问两个类定来指定访问两个类A A实例中的哪一个。实例中的哪一个。 【例例8.78.7】读程序,分析运行结果读

57、程序,分析运行结果Database & Information System Lab58http:/二义性问题二义性问题 本例的类间继承关系示例如下本例的类间继承关系示例如下: :class Aclass B : public Aclass C : public Aclass D : public B, public C 存储结构示意存储结构示意: :( ( (A) B ) ( (A) C ) D ) 上述多级混合继承关系应用例举上述多级混合继承关系应用例举: : 例例1.1.类类A-A-人员类;人员类; 类类B-B-学生类;学生类; 类类C-C-助教类;助教类; 类类D-D-学生助教

58、类。学生助教类。 例例2.2.类类A-A-人员类;人员类; 类类B-B-学生类;学生类; 类类C-C-工人类;工人类; 类类D-D-工人学生类。工人学生类。 例例3.3.类类A-A-家具类;家具类; 类类B-B-沙发类;沙发类; 类类C-C-床类;床类; 类类D-D-沙发床类。沙发床类。Database & Information System Lab59http:/二义性问题二义性问题#include using namespace std;class A public:int a;A(int x)a=x; void showall()couta=aendl;class B:publ

59、ic A public:int b;B(int x):A(x-1)b=x;Database & Information System Lab60http:/二义性问题二义性问题class C:public A public:int c; C(int x):A(x-1)c=x;Database & Information System Lab61http:/二义性问题二义性问题class D:public B,public C public:int d;D(int x, int y, int z):B(x+1),C(y+2)d=z;void showall() coutC:a=C

60、:aendl;/在类在类D定义范围内,要通过类名限定来指定定义范围内,要通过类名限定来指定/访问两个类访问两个类A实例中的哪一个实例中的哪一个coutB:a=B:aendl;coutb,c,d=b, c, dendl;/b、c、d不重名,具有唯一性不重名,具有唯一性 ;Database & Information System Lab62http:/二义性问题二义性问题void main() D Dobj(101, 202, 909); Dobj.showall();cout-endl;coutDobj.C:a=Dobj.C:aendl;/访问类访问类D的从的从C继承而来的继承而来的acoutDobj.B:a=Dobj.B:aendl;程序执行后的显示结果如下:程序执行后的显示结果如下:C:a=203B:a=101b,c,d=102, 204, 909-Dobj.C:a=203Dobj.B:a=101Database & Information System Lab63http:/作业作业8.18.1v设计日期类和时间类,并以此两类为基类设计日期类和时间类,并以此两类为基类派生日期时间类派生日期时间类 要求:要求: 日期类包括年、月、日等成员日期类包括年、月、日等成员 时间类包括

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论