1、第4章 继承与组合1234继承与派生的概念继承与派生的概念第第4章章 继承与组合继承与组合本章学习要点本章学习要点派生类的构成派生类的构成派生类的声明方式派生类的声明方式派生类中基类成员的访问属性派生类中基类成员的访问属性25678派生类的构造函数和析构函数派生类的构造函数和析构函数第第4章章 继承与组合继承与组合本章学习要点本章学习要点基类与派生类对象的关系基类与派生类对象的关系多重继承多重继承组合组合对象组成对象对象组成对象3本章学习目标本章学习目标1.理解继承和派生的概念;理解继承和派生的概念;2.掌握派生类的声明方式,派生类的构成;掌握派生类的声明方式,派生类的构成;3.掌握三种不同继
2、承方式对基类成员、派生类成员掌握三种不同继承方式对基类成员、派生类成员访问权限的影响;访问权限的影响;3.掌握派生类的构造函数和析构函数的执行时机;掌握派生类的构造函数和析构函数的执行时机;4.掌握多重继承的声明方法;多重继承派生类的掌握多重继承的声明方法;多重继承派生类的 构造函数与析构函数的定义及执行;构造函数与析构函数的定义及执行;5.理解虚基类的概念,掌握其作用和声明方法;理解虚基类的概念,掌握其作用和声明方法;6.理解组合的概念,掌握继承与组合在软件开发中理解组合的概念,掌握继承与组合在软件开发中 的意义。的意义。第第4章章 继承与组合继承与组合4现实世界中的例子现实世界中的例子几何
3、形状几何形状矩形矩形圆圆汽车汽车工具车工具车轿车轿车面包车面包车旅行车旅行车 卡车卡车交通工具交通工具小汽车小汽车飞机飞机船船5现实世界中的例子现实世界中的例子猴子猴子鸟鸟猫科猫科动物动物狮子狮子猎豹猎豹虎虎销售经理销售经理经理经理工人工人销售人员销售人员职员职员6v面向对象技术强调软件的可重用性面向对象技术强调软件的可重用性(software reusability)。C+语言提供了类的继承机制,解语言提供了类的继承机制,解决了软件重用问题。决了软件重用问题。第第4章章 继承与组合继承与组合v通过继承机制,可以方便地利用一个已有的类建通过继承机制,可以方便地利用一个已有的类建立新类,重用已有
4、软件中的部分甚至很大的部分。立新类,重用已有软件中的部分甚至很大的部分。v微软基础类微软基础类MFC,就是通过类的继承来体现类的就是通过类的继承来体现类的可重用性和可扩充性可重用性和可扩充性7v在在C+中,所谓中,所谓“继承继承”就是在一个或多就是在一个或多个已存在的类的基础上建立一个新的类。个已存在的类的基础上建立一个新的类。已存在的类称为已存在的类称为“基类基类”、“父类父类”或或“一般类一般类”。新建立的类称为。新建立的类称为“派生类派生类”、“子类子类”或或“特殊类特殊类”。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与组合继承与组合8v一个新类从已有的类那里获得其已有特性
5、,这种一个新类从已有的类那里获得其已有特性,这种现象称为现象称为类的继承类的继承。通过继承,一个新建子类从。通过继承,一个新建子类从已有的父类那里获得父类的特性。已有的父类那里获得父类的特性。v从另一角度说,从已有的父类产生一个新的子类从另一角度说,从已有的父类产生一个新的子类,称为,称为类的派生类的派生。类的继承是用已有的类来建立。类的继承是用已有的类来建立专用类的编程技术。专用类的编程技术。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与组合继承与组合9v派生类派生类继承继承了基类的所有数据成员和成员函数(不了基类的所有数据成员和成员函数(不包括基类的构造函数和析构函数),并可以
6、包括基类的构造函数和析构函数),并可以增加增加自自己的新成员,同时也可以己的新成员,同时也可以调整调整来自基类的数据成员来自基类的数据成员和成员函数。和成员函数。v基类和派生类是相对而言的。基类和派生类是相对而言的。一个基类可以派生出一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生多个派生类,每一个派生类又可以作为基类再派生出新的派生类。一代一代地派生下去,就形成了类出新的派生类。一代一代地派生下去,就形成了类的继承层次结构的继承层次结构4.1 继承与派生的概念继承与派生的概念第第4章章 继承与组合继承与组合10图图4-1 单继承单继承中学生中学生学生学生初中生初中生高中生高中生
7、专科生专科生本科生本科生研究生研究生 硕士生硕士生博士生博士生大学生大学生小学生小学生留学生留学生一个派生类只从一个基类派生,这称为单继承一个派生类只从一个基类派生,这称为单继承(single(single inheritance)inheritance),这种继承关系所形成的层次是一个树这种继承关系所形成的层次是一个树形结构,可以用图形结构,可以用图4-14-1表示。表示。第第4章章 继承与组合继承与组合11图图4-2 4-2 多继承多继承销售经理销售经理经理经理工人工人销售人员销售人员职员职员一个派生类不仅可以从一个基类派生,也可以从多个一个派生类不仅可以从一个基类派生,也可以从多个基类派
8、生。基类派生。一个派生类有两个或多个基类的称为多重一个派生类有两个或多个基类的称为多重继承继承(multiple inheritance),这种继承关系所形成的这种继承关系所形成的结构如图结构如图4-2所示。所示。第第4章章 继承与组合继承与组合v基类和派生类的关系,可以表述为:基类和派生类的关系,可以表述为:派生类是基类的具体化,而基类是派生类的抽派生类是基类的具体化,而基类是派生类的抽象。象。4.1 继承与派生的概念继承与派生的概念第第4章章 继承与组合继承与组合13v单继承派生类的声明格式如下:单继承派生类的声明格式如下:class 派生类名派生类名:继承方式继承方式 基类名基类名 派生
9、类新增加的成员派生类新增加的成员;4.2 派生类的声明方式派生类的声明方式第第4章章 继承与组合继承与组合 继承方式可以是继承方式可以是public(公用的公用的)、private(私有私有的的)、protected(受保护的受保护的)。此项是可选的,如。此项是可选的,如果不写此项,则默认为果不写此项,则默认为private(私有的私有的)。14class Circle /声明基类声明基类public:/基类公用成员基类公用成员 void SetRadius(int r)radius=r;int GetRadius()return radius;void ShowRadius()coutBas
10、e class Circle:radius=radius endl;private:/基类私有成员基类私有成员 int radius;15class Cylinder:public Circlepublic:void SetHeight(int h)height=h;int GetHeight()return height;void ShowHeight()coutDerived class Cylinder:height=height endl;private:int height;第第4章章 继承与组合继承与组合图图4-3 4-3 基类基类CircleCircle和派生类和派生类Cylin
11、derCylinder的成员示意图的成员示意图16v派生类中的成员派生类中的成员包包从基类继承过来的成员从基类继承过来的成员括括和和自己新增加的成员自己新增加的成员两大部分,从基类继承两大部分,从基类继承过来的成员体现了派生类从基类继承而获得过来的成员体现了派生类从基类继承而获得的共性,而新增加的成员体现了派生类的个的共性,而新增加的成员体现了派生类的个性,体现了派生类与基类的不同,体现了不性,体现了派生类与基类的不同,体现了不同派生类的区别。同派生类的区别。4.3 派生类的派生类的构成构成第第4章章 继承与组合继承与组合17184.3 派生类的派生类的构成构成v从基类接收成员。从基类接收成员
12、。派生类把基类全部的成员(不包括构造函派生类把基类全部的成员(不包括构造函数和析构函数)接收过来,也就是说没有数和析构函数)接收过来,也就是说没有选择的,不能选择接收其中一部分成员,选择的,不能选择接收其中一部分成员,而舍弃另一部分成员。而舍弃另一部分成员。v调整从基类接收的成员。调整从基类接收的成员。v在声明派生类时增加的成员。在声明派生类时增加的成员。接收基类成员是程序员不能选择的,但是接收基类成员是程序员不能选择的,但是程序人员可以对这些成员作某些调整。程序人员可以对这些成员作某些调整。改变访问属性;改变访问属性;用同名新成员覆盖基类的同名成员;用同名新成员覆盖基类的同名成员;它体现了派
13、生类对基类的扩展。它体现了派生类对基类的扩展。定义派生类的构造函数和析构函数。定义派生类的构造函数和析构函数。19派生类成员的访问属性v 在讨论访问属性时,需要考虑以下几种情况:在讨论访问属性时,需要考虑以下几种情况:基类的成员函数访问基类成员;基类的成员函数访问基类成员;派生类的成员函数访问派生类自己增加的派生类的成员函数访问派生类自己增加的成员;成员;派生类的成员函数访问基类成员;派生类的成员函数访问基类成员;在派生类外访问派生类的成员;在派生类外访问派生类的成员;在派生类外访问基类的成员;在派生类外访问基类的成员;v派生类中基类成员的访问属性派生类中基类成员的访问属性不仅不仅与在声明基与
14、在声明基类时所声明的访问属性有关,类时所声明的访问属性有关,而且而且与在声明派与在声明派生类时所指定的对基类的继承方式有关生类时所指定的对基类的继承方式有关,这两,这两个因素共同决定基类成员在派生类中的访问属个因素共同决定基类成员在派生类中的访问属性。性。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与组合继承与组合20v派生类对基类的继承方式有派生类对基类的继承方式有public,private和和protected 3种。不同的继承方式决定了基类成员在派种。不同的继承方式决定了基类成员在派生类中的访问属性。生类中的访问属性。v(1)公用继承公用继承(publi
15、c inheritance)v 基类的公用成员和保护成员在派生类中保持原有基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。访问属性,其私有成员仍为基类私有。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与组合继承与组合21v(2)私有继承私有继承(private inheritance)v 基类的公用成员和保护成员在派生类中成了私有成基类的公用成员和保护成员在派生类中成了私有成员。其私有成员仍为基类私有。员。其私有成员仍为基类私有。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与组合继承与组合22v(3)受
16、保护的继承受保护的继承(protected inheritance)v 基类的公用成员和保护成员在派生类中成了保护成基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。员,其私有成员仍为基类私有。v 保护成员的意思是保护成员的意思是:不能被外界访问,但可以被派不能被外界访问,但可以被派生类的成员访问。生类的成员访问。4.4 派生类中基类成员的访问属性派生类中基类成员的访问属性第第4章章 继承与组合继承与组合23v在在声明声明一个派生类时将基类的继承方式指定为一个派生类时将基类的继承方式指定为public的,称为的,称为公用继承公用继承。v用公用继承方式建立的派生类称为用公用
17、继承方式建立的派生类称为公用派生类公用派生类(public derived class),其基类称为,其基类称为公用基类公用基类(public base class)。4.4.1 公用继承公用继承第第4章章 继承与组合继承与组合244.4.1 公用继承公用继承第第4章章 继承与组合继承与组合表表4-1 4-1 公用基类成员在派生类中的访问属性公用基类成员在派生类中的访问属性公用基类的成员公用基类的成员在公用派生类中的访问属性在公用派生类中的访问属性私有成员私有成员不可访问不可访问公用成员公用成员公用公用保护成员保护成员保护保护25第第4章章 继承与组合继承与组合【例例4-1】公用继承的例子。公
18、用继承的例子。#include using namespace std;class Circle /声明基类声明基类public:/基类公用成员基类公用成员 void SetRadius(int r)radius=r;int GetRadius()return radius;void ShowRadius()coutBase class Circle:radius=radius endl;private:/基类私有成员基类私有成员 int radius;26class Cylinder:public Circlepublic:void SetHeight(int h)height=h;int
19、GetHeight()return height;void ShowHeight()coutDerived class Cylinder:height=height endl;void Set(int r,int h)/radius=r;SetRadius(r);height=h;void Show()/coutradius=radiusendl;cout radius=GetRadius()endl;/ShowRadius();cout height=height endl;private:int height;27 int main()Cylinder obj;obj.SetRadius(
20、10);obj.showRadius();obj.SetHeight(20);obj.ShowHeight();obj.Set(30,40);obj.Show();return 0;第第4章章 继承与组合继承与组合程序运行结果如下:程序运行结果如下:Base class Circle:radius=10Derived class Cylinder:height=20radius=30height=40 2829公有继承举例公有继承举例class Point/基类基类Point类的声明类的声明public:/公有函数成员公有函数成员void InitP(float xx=0,float yy=0
21、)X=xx;Y=yy;void Move(float xOff,float yOff)X+=xOff;Y+=yOff;float GetX()return X;float GetY()return Y;private:/私有数据成员私有数据成员float X,Y;30class Rectangle:public Point /派生类声明派生类声明public:/新增公有函数成员新增公有函数成员void InitR(float x,float y,float w,float h)InitP(x,y);W=w;H=h;/调用基类公有成员函数调用基类公有成员函数float GetH()return
22、H;float GetW()return W;private:/新增私有数据成员新增私有数据成员float W,H;公有继承举例公有继承举例31int main()Rectangle rect;rect.InitR(2,3,20,10);/通过派生类对象访问基类公有成员通过派生类对象访问基类公有成员rect.Move(3,2);coutrect.GetX(),rect.GetY(),rect.GetH(),rect.GetW()endl;return 0;公有继承举例公有继承举例复习复习v 有类有类Point如下:如下:class Point/基类基类Point类的声明类的声明public:/
23、公有函数成员公有函数成员void InitP(float xx=0,float yy=0)X=xx;Y=yy;void Move(float xOff,float yOff)X+=xOff;Y+=yOff;float GetX()return X;float GetY()return Y;private:/私有数据成员私有数据成员float X,Y;以以Point为父类,定义为父类,定义一个子类一个子类Circle类,继类,继承方式为承方式为公有公有继承,继承,Circle类中新增私有数类中新增私有数据成员据成员r和公有成员函数和公有成员函数GetR(),要求在,要求在main()()函数中,
24、子类对象能够函数中,子类对象能够使用使用InitP(),Move(),GetX(),GetY()和和GetR()。v在声明一个派生类时将基类的继承方式指定为在声明一个派生类时将基类的继承方式指定为private的,称为的,称为私有继承私有继承。v用私有继承方式建立的派生类称为用私有继承方式建立的派生类称为私有派生类私有派生类(private derived class),其基类称为,其基类称为私有基类私有基类(private base class)。4.4.2 私有继承私有继承第第4章章 继承与组合继承与组合334.4.2 私有继承私有继承第第4章章 继承与组合继承与组合表表4-2 4-2 私
25、有基类成员在派生类中的访问属性私有基类成员在派生类中的访问属性私有基类的成员私有基类的成员在私有派生类中的访问属性在私有派生类中的访问属性私有成员私有成员不可访问不可访问公用成员公用成员私有私有保护成员保护成员私有私有34第第4章章 继承与组合继承与组合【例例4-24-2】将将【例例4-14-1】中的公用继承方式改为用私有中的公用继承方式改为用私有继承方式。继承方式。class Circle /声明基类声明基类Circle圆类圆类public:/Circle类公用成员函数类公用成员函数 void SetRadius(int r)radius=r;int GetRadius()return ra
26、dius;void ShowRadius()cout Base class Circle:radius=radius endl;private:/Circle类私有数据成员类私有数据成员 int radius;/圆半径圆半径;35第第4章章 继承与组合继承与组合 class Cylinder:private Circle public:/Cylinder类公用成员函数类公用成员函数 void SetHeight(int h)height=h;int GetHeight()return height;void ShowHeight()cout Derived class Cylinder:hei
27、ght=height endl;void Set(int r,int h)SetRadius(r);height=h;void Show()cout radius=GetRadius()endl;cout height=height endl;private:/Cylinder类私有数据成员类私有数据成员 int height;/圆柱体高度圆柱体高度;int main()Cylinder obj;/obj.SetRadius(10);/obj.ShowRadius();obj.SetHeight(20);obj.ShowHeight();obj.Set(30,40);obj.Show();re
28、turn 0;第第4章章 继承与组合继承与组合3738私有继承举例私有继承举例class Point/基类基类Point类的声明类的声明public:/公有函数成员公有函数成员void InitP(float xx=0,float yy=0)X=xx;Y=yy;void Move(float xOff,float yOff)X+=xOff;Y+=yOff;float GetX()return X;float GetY()return Y;private:/私有数据成员私有数据成员float X,Y;39私有继承举例私有继承举例class Rectangle:private Point/派生类声
29、明派生类声明public:/新增外部接口新增外部接口void InitR(float x,float y,float w,float h)InitP(x,y);W=w;H=h;/访问基类公有成员访问基类公有成员void Move(float xOff,float yOff)Point:Move(xOff,yOff);float GetX()return Point:GetX();float GetY()return Point:GetY();float GetH()return H;float GetW()return W;private:/新增私有数据新增私有数据float W,H;/flo
30、at GetX()return Point:GetX();/float GetY()return Point:GetY();40int main()/通过派生类对象只能访问本类成员通过派生类对象只能访问本类成员 Rectangle rect;rect.InitR(2,3,20,10);rect.Move(3,2);coutrect.GetX(),rect.GetY(),rect.GetH(),rect.GetW()endl;return 0;40私有继承举例私有继承举例复习复习v 有类有类Point如下:如下:class Point/基类基类Point类的声明类的声明public:/公有函数成
31、员公有函数成员void InitP(float xx=0,float yy=0)X=xx;Y=yy;void Move(float xOff,float yOff)X+=xOff;Y+=yOff;float GetX()return X;float GetY()return Y;private:/私有数据成员私有数据成员float X,Y;以以Point为父类,定义为父类,定义一个子类一个子类Circle类,继类,继承方式为承方式为私有私有继承,继承,Circle类中新增私有数类中新增私有数据成员据成员r和公有成员函数和公有成员函数GetR()和和InitC(),要求,要求在在main()函数
32、中,子类函数中,子类对象能够使用对象能够使用InitP(),Move(),GetX(),GetY()和和GetR()。v由由protected声明的成员称为声明的成员称为“受保护的成员受保护的成员”,简称,简称“保护成员保护成员”。从类的用户角度来看,保护成员等价。从类的用户角度来看,保护成员等价于私有成员。但有一点与私有成员不同,保护成员可于私有成员。但有一点与私有成员不同,保护成员可以被派生类的成员函数访问。以被派生类的成员函数访问。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与组合继承与组合42v在定义一个派生类时将基类的继承方式指定为在定义一个派生类时将基类的继承方
33、式指定为protected的,称为的,称为保护继承保护继承。v用保护继承方式建立的派生类称为用保护继承方式建立的派生类称为保护派生类保护派生类(protected derived class),其基类称为受保护的基类,其基类称为受保护的基类(protected base class),简称,简称保护基类保护基类。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与组合继承与组合43第第4章章 继承与组合继承与组合表表4-3 4-3 基类成员在派生类中的访问属性基类成员在派生类中的访问属性4.4.3 保护成员和保护继承保护成员和保护继承基类中的基类中的成员成员在在公用派生类公用派生
34、类中的访问属性中的访问属性在在私有派生类私有派生类中的访问属性中的访问属性在在保护派生类保护派生类中的访问属性中的访问属性私有成员私有成员不可访问不可访问不可访问不可访问不可访问不可访问公用成员公用成员公用公用私有私有保护保护保护成员保护成员保护保护私有私有保护保护44通过以上的介绍,可以知道:通过以上的介绍,可以知道:v(1)在派生类中,成员有)在派生类中,成员有4种不同的访问属性:种不同的访问属性:v 公用的:公用的:派生类内和派生类外都可以访问。派生类内和派生类外都可以访问。v 受保护的:受保护的:派生类内可以访问,派生类外不能访问派生类内可以访问,派生类外不能访问,其下一层的派生类可以
35、访问。,其下一层的派生类可以访问。v 私有的:私有的:派生类内可以访问,派生类外不能访问。派生类内可以访问,派生类外不能访问。v 不可访问的:不可访问的:派生类内和派生类外都不能访问。派生类内和派生类外都不能访问。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与组合继承与组合45第第4章章 继承与组合继承与组合表表4-44-4派生类中的成员的访问属性派生类中的成员的访问属性派生类中的成员派生类中的成员在派生类在派生类中中在派生类在派生类外外在下层公用派在下层公用派生类中生类中派生类中访问属性派生类中访问属性为公用的成员为公用的成员可以可以可以可以可以可以派生类中访问属性派生类
36、中访问属性为受保护的成员为受保护的成员可以可以不可以不可以可以可以派生类中访问属性派生类中访问属性为私有的成员为私有的成员可以可以不可以不可以不可以不可以在派生类中不可访在派生类中不可访问的成员问的成员不可以不可以不可以不可以不可以不可以46v(2)类的成员在不同作用域中有不同的访问属性类的成员在不同作用域中有不同的访问属性,对这一点要十分清楚。对这一点要十分清楚。4.4.3 保护成员和保护继承保护成员和保护继承第第4章章 继承与组合继承与组合47第第4章章 继承与组合继承与组合【例例4-34-3】保护继承的例子。保护继承的例子。48class Circle /声明基类声明基类Circle圆类
37、圆类public:/Circle类公用成员函数类公用成员函数 void SetRadius(int r)radius=r;int GetRadius()return radius;void ShowRadius()cout Base class Circle:radius=radius endl;private:/Circle类私有数据成员类私有数据成员 int radius;/圆半径圆半径;第第4章章 继承与组合继承与组合/以以protected方式声明保护派生类方式声明保护派生类Cylinderclass Cylinder:protected Circle public:/Cylinder
38、类公用成员函数类公用成员函数 void SetHeight(int h)height=h;int GetHeight()return height;void ShowHeight()cout Derived class Cylinder:height=height endl;void Set(int r,int h)SetRadius(r);height=h;void Show()cout radius=GetRadius()endl;cout height=height endl;private:/Cylinder类私有数据成员类私有数据成员 int height;/圆柱体高度圆柱体高度;i
39、nt main()Cylinder obj;/obj.SetRadius(10);/obj.ShowRadius();obj.SetHeight(20);obj.ShowHeight();obj.Set(30,40);obj.Show();return 0;第第4章章 继承与组合继承与组合5051保护继承举例保护继承举例class Point/基类基类Point类的声明类的声明public:/公有函数成员公有函数成员void InitP(float xx=0,float yy=0)X=xx;Y=yy;void Move(float xOff,float yOff)X+=xOff;Y+=yOff
40、;float GetX()return X;float GetY()return Y;private:/私有数据成员私有数据成员float X,Y;52保护继承举例保护继承举例class Rectangle:protected Point/派生类声明派生类声明public:/新增外部接口新增外部接口void InitR(float x,float y,float w,float h)InitP(x,y);W=w;H=h;/访问基类公有成员访问基类公有成员float GetH()return H;float GetW()return W;private:/新增私有数据新增私有数据float W,
41、H;float GetX()return Point:GetX();float GetY()return Point:GetY();void Move(float xOff,float yOff)Point:Move(xOff,yOff);53int main()Rectangle rect;rect.InitR(2,3,20,10);rect.Move(3,2);coutrect.GetX(),rect.GetY(),rect.GetH(),rect.GetW()endl;return 0;53错误,不能在类外通过错误,不能在类外通过派生类的对象来访问基派生类的对象来访问基类的成员函数类的成
42、员函数Move()、GetX()和和GetY()保护继承举例保护继承举例54class B:public A /public方式方式public:void f3();protected:void f4();private:int m;class C:protected B /protected方式方式public:void f5();private:int n;class A public:int i;protected:void f2();int j;private:int k;练习练习vP134 第一题第一题55v在前面介绍派生类的构成时曾提到:可以在派生类在前面介绍派生类的构成时曾提到:
43、可以在派生类中声明一个与基类成员同名的成员,则派生类的新中声明一个与基类成员同名的成员,则派生类的新成员会屏蔽与其同名的基类成员,使同名的基类成成员会屏蔽与其同名的基类成员,使同名的基类成员成为员成为“不可见不可见”的,即基类成员的名字被隐藏。的,即基类成员的名字被隐藏。4.4.4 派生类对基类成员的重定义派生类对基类成员的重定义 和名字隐藏和名字隐藏第第4章章 继承与组合继承与组合56第第4章章 继承与组合继承与组合【例例4-44-4】派生类重定义基类成员函数的例子。派生类重定义基类成员函数的例子。#include using namespace std;class Circle /声明基类
44、声明基类Circlepublic:/基类基类Circle的公用成员函数的公用成员函数 void Set(int r)radius=r;void Show()cout Base class Circle:radius=radius endl;private:/基类基类Circle的私有数据成员的私有数据成员 int radius;/圆半径圆半径;57第第4章章 继承与组合继承与组合class Cylinder:public Circlepublic:void Set(int r,int h)Base:Set(r);height=h;void Show()Base:Show();cout Deri
45、ved class Cylinder:height=“height endl;private:int height;58 int main()Cylinder obj;obj.Set(10,20);obj.Show();/obj.Set(10);obj.Circle:Set(30);obj.Circle:Show();return 0;第第4章章 继承与组合继承与组合59从上例可以看出:从上例可以看出:v(1)如果是在派生类中声明了一个与基类成员函数)如果是在派生类中声明了一个与基类成员函数名字相同,参数也相同的成员函数,则基类中的成名字相同,参数也相同的成员函数,则基类中的成员函数将被隐藏。
46、员函数将被隐藏。v(2)如果是在派生类中声明了一个与基类成员函数)如果是在派生类中声明了一个与基类成员函数名字相同,但参数不同的成员函数,则基类中的成名字相同,但参数不同的成员函数,则基类中的成员函数也将被隐藏。员函数也将被隐藏。4.4.4 派生类对基类成员的重定义和名字隐藏派生类对基类成员的重定义和名字隐藏第第4章章 继承与组合继承与组合60第第4章章 继承与组合继承与组合【例】派生类重定义基类数据成员的例子。【例】派生类重定义基类数据成员的例子。#include using namespace std;class Base /声明基类声明基类public:/基类公用成员基类公用成员 flo
47、at y;void set(int n)x=n;void show()coutBase class:x=x endl;private:/基类私有成员基类私有成员 int x;61第第4章章 继承与组合继承与组合/以以public方式声明派生类方式声明派生类Derived class Derived:public Basepublic:void set(int i,int j,int k)Base:set(i);y=j;z=k;void show()Base:show();coutBase class:y=Base:yendl;coutDerived class:y=yendl;coutDeri
48、ved class:z=zendl;private:int y,z;62 int main()Derived obj;obj.set(1,2,3);obj.Base:y=12.3;obj.show();return 0;第第4章章 继承与组合继承与组合程序运行结果如下:程序运行结果如下:Base class:x=1Base class:x=1Base class:y=12.3Base class:y=12.3Derived class:y=2Derived class:y=2Derived class:z=3Derived class:z=363v由于基类的构造函数和析构函数派生类是不能继承的
49、由于基类的构造函数和析构函数派生类是不能继承的。在声明派生类时,一般还应当自己定义派生类的构。在声明派生类时,一般还应当自己定义派生类的构造函数和析构函数。造函数和析构函数。4.5 派生类的构造函数和析构函数派生类的构造函数和析构函数第第4章章 继承与组合继承与组合64v构造函数的作用是在创建对象时对对象的数据成员进构造函数的作用是在创建对象时对对象的数据成员进行初始化。行初始化。派生类数据成员包括从基类继承过来的数派生类数据成员包括从基类继承过来的数据成员和自己新增加的数据成员,据成员和自己新增加的数据成员,在设计派生类的构在设计派生类的构造函数时,造函数时,不仅要考虑派生类新增数据成员的初
50、始化不仅要考虑派生类新增数据成员的初始化,还应当考虑对其从基类继承过来的数据成员的初始,还应当考虑对其从基类继承过来的数据成员的初始化。化。采取的方法是在执行派生类的构造函数时,调用采取的方法是在执行派生类的构造函数时,调用基类的构造函数。基类的构造函数。4.5.1 派生类构造函数派生类构造函数第第4章章 继承与组合继承与组合65下面从最简单的派生类构造函数的定义说起。下面从最简单的派生类构造函数的定义说起。v所谓简单的派生类是指只有一个基类,而且只有一级所谓简单的派生类是指只有一个基类,而且只有一级派生,在派生类的数据成员中不包含其他类对象的派派生,在派生类的数据成员中不包含其他类对象的派生