课件四类的继承和派生_第1页
课件四类的继承和派生_第2页
课件四类的继承和派生_第3页
课件四类的继承和派生_第4页
课件四类的继承和派生_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

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

文档简介

1、C+语言程序设计语言程序设计第第4章章 类的继承与派生类的继承与派生2中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China 本章主要内容本章主要内容类的继承与派生类的继承与派生派生类成员的访问属性派生类成员的访问属性派生类的构造函数和析构函数派生类的构造函数和析构函数多重继承多重继承3中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系

2、基础教研室 2013-2North University of China4.1类的继承与派生类的继承与派生一、基本概念一、基本概念1. 派生与继承的意义派生与继承的意义n继承性继承性 是面向对象程序设计语言的基本特性是面向对象程序设计语言的基本特性之一,是指在已有类的基础上建立新的类。之一,是指在已有类的基础上建立新的类。n它允许在构造软件系统的层次结构中利用已它允许在构造软件系统的层次结构中利用已存在类的部分或全部内容,从而大大提高了存在类的部分或全部内容,从而大大提高了软件的重用性。软件的重用性。n派生类派生类 它是继承的直接产物它是继承的直接产物,它是通过继承已它是通过继承已有类而产生

3、的新类,是代码重用的具体实现。有类而产生的新类,是代码重用的具体实现。4中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China昆虫昆虫有翅有翅无翅无翅蛾蛾苍蝇苍蝇蝴蝶蝴蝶如图:昆虫分类如图:昆虫分类5中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China2. 派生与继

4、承的概念派生与继承的概念继承:在定义一个类继承:在定义一个类A时,若它使用了一时,若它使用了一个已定义类个已定义类B的部分或全部成员的部分或全部成员,则称类则称类A继承了类继承了类B,并称类,并称类 B为基类或父类为基类或父类,称称类类A为派生类或子类。为派生类或子类。派生:在派生:在C+语言中,称一个类继承另语言中,称一个类继承另一个类的过程为派生一个类。一个类的过程为派生一个类。6中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of C

5、hina 3.基类和派生类基类和派生类n基类基类(父类父类) :已存在的用来派生新类的类;已存在的用来派生新类的类;n派生类派生类(子类子类):由已存在的类派生出的新类;:由已存在的类派生出的新类;n单继承单继承:从:从一个基类一个基类派生的继承;派生的继承;n多继承多继承:从:从多个基类多个基类派生的继承;派生的继承;基类基类派生类派生类ABACB单继承单继承多继承多继承基类与派生类基类与派生类单继承与多继承单继承与多继承7中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2

6、North University of China二、派生类的定义格式二、派生类的定义格式class : ;1.单继承派生类的声明形式:单继承派生类的声明形式:8中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China二、派生类的定义格式二、派生类的定义格式(续续) 2. 继承方式继承方式public:公有公有继承;继承;private:私有私有继承;继承;protected:保护保护继承;继承;作用:控制基类中声明的成员在多大的范

7、作用:控制基类中声明的成员在多大的范围内能被派生类的用户访问围内能被派生类的用户访问;9中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China派生类派生类私有成员私有成员公有成员公有成员保护成员保护成员私有成员私有成员公有成员公有成员保护成员保护成员基类部分基类部分新定义部分新定义部分派生类成员派生类成员派生类的构成派生类的构成三、派生类的构成三、派生类的构成10中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系

8、基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China构造派生类的过程:构造派生类的过程:n从基类接收成员;从基类接收成员;n调整从基类接收的成员;调整从基类接收的成员;n声明派生类的新增成员;声明派生类的新增成员;n定义派生类的构造函数和析构函数。定义派生类的构造函数和析构函数。三、派生类的构成三、派生类的构成(续续)11中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2Nor

9、th University of China四、基类与派生类的关系四、基类与派生类的关系基类是对若干个派生类的抽象,而派生类是基基类是对若干个派生类的抽象,而派生类是基类的具体化;基类抽取了它的派生类的公共特征,类的具体化;基类抽取了它的派生类的公共特征,而派生类通过增加行为将抽象类变为某种有用的类而派生类通过增加行为将抽象类变为某种有用的类型。型。1、派生类是基类的具体化派生类是基类的具体化2、派生类是基类定义的延续派生类是基类定义的延续派生类将其自身与基类区别开来的方法是添加派生类将其自身与基类区别开来的方法是添加数据成员和成员函数;数据成员和成员函数;3、派生类是基类的组合派生类是基类的

10、组合12中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China 4.2派生类成员的派生类成员的访问属性访问属性公有基类公有基类公有派生类公有派生类特点:特点:n基类的公有成员和保护成员作为派生类的成基类的公有成员和保护成员作为派生类的成员时,都保持原有的访问属性,而基类的私员时,都保持原有的访问属性,而基类的私有成员仍然为基类私有。有成员仍然为基类私有。 公有继承公有继承(public)13中北大学计算机系基础教研室中北大学计算机

11、系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China私有基类私有基类私有派生类私有派生类特点:特点:n基类的公有成员和保护成员作为派生类的成基类的公有成员和保护成员作为派生类的成员时,都作为派生类的私有成员,且不能被员时,都作为派生类的私有成员,且不能被这一派生类的子类访问,而基类的私有成员这一派生类的子类访问,而基类的私有成员仍然为基类私有。仍然为基类私有。n不能通过派生类对象引用从私有基类继承过不能通过派生类对象引用从私有基类继承过来的任何成员。来的任何成员。 4

12、.2派生类成员的派生类成员的访问属性访问属性 (续续) 私有继承私有继承(private)14中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China 保护继承保护继承(protected) 4.2派生类成员的派生类成员的访问属性访问属性 (续续)保护成员:受保护的成员不能被类的外保护成员:受保护的成员不能被类的外部访问,但可以被派生类成员函数访问部访问,但可以被派生类成员函数访问保护继承保护继承n保护基类保护基类n保护派生类保护派

13、生类n特点:基类的公有成员和保护成员作为派生特点:基类的公有成员和保护成员作为派生类的成员时,都作为派生类的保护成员,而类的成员时,都作为派生类的保护成员,而基类的私有成员仍然为基类私有基类的私有成员仍然为基类私有.15中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China基类的访问特性基类的访问特性类的继承特性类的继承特性子类的访问特性子类的访问特性PublicProtectedPrivatePublicPublicProtec

14、tedNo accessPublicProtectedPrivateProtectedProtectedProtectedNo accessPublicProtectedPrivatePrivatePrivatePrivateNo access表:继承对基类成员的访问能力表:继承对基类成员的访问能力 4.2派生类成员的派生类成员的访问属性访问属性 (续续)16中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China类类B为类为类A的

15、直接派生类,的直接派生类,类类C为类为类A的间接派生类;的间接派生类;类类A是类是类B的直接基类,的直接基类, 是类是类C的间接基类;的间接基类;类类C对类对类A的成员的访问属的成员的访问属性,由类性,由类A成员的访问属性、成员的访问属性、类类B的继承方式、类的继承方式、类C的继的继承方式共同决定。承方式共同决定。 4.2派生类成员的派生类成员的访问属性访问属性 (续续) 多级派生的访问属性多级派生的访问属性类类 A类类 B类类 C17中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2

16、013-2North University of China例例分析下列程序中的访问权限。分析下列程序中的访问权限。 4.2派生类成员的派生类成员的访问属性访问属性 (续续)class Locationpublic: void InitL(int xx,int yy); void Move(int xOff,int yOff); int GetX() return X; int GetY() return Y;private: int X,Y;void Location:InitL(int xx,int yy) X=xx; Y=yy;void Location:Move(int xOff,in

17、t yOff) X+=xOff; Y+=yOff;18中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaclass Rectangle:public Locationpublic: void InitR(int x,int y,int w,int h); int GetH() return H; int GetW() return W;private: int H,W;void Rectangle:InitR(int x,in

18、t y,int w,int h) InitL(x,y); W=w; H=h;公有继承公有继承19中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China#include using namespace std;void main() Rectangle rect; rect.InitR(2,3,20,10); rect.Move(3,2); coutrect.GetX(), rect.GetY(), rect.GetH(), rec

19、t.GetW()endl;输出:输出:5,5,10,2020中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China/派生类派生类class V:public Rectanglepublic: void Function();void V:Function() Move(3,2);公有继承公有继承若继承方式为private,Move(3,2)是否正确?为什么?若继承方式为若继承方式为private,Move(3,2)仍然仍然正确正确

20、。原因原因:由于类:由于类Rectangle对类对类Location是公有继承,是公有继承,而类而类V对类对类Rectangle是是直接继承直接继承,因此在类,因此在类V内内可以访问基类可以访问基类Location的公有成员的公有成员;21中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaclass Rectangle:private Locationpublic: void InitR(int x,int y,int w,i

21、nt h); int GetH() return H; int GetW() return W;private: int W,H;void Rectangle:InitR(int x,int y,int w,int h) InitL(x,y); W=w; H=h;私有继承私有继承直接继承,正确直接继承,正确22中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China#include void main() Rectangle rec

22、t; rect.InitR(2,3,20,10); rect.Move(3,2); coutrect.GetX(), rect.GetY(), rect.GetH(), rect.GetW()endl;错误/修改修改class Rectangle:private Locationpublic: void InitR(int x,int y,int w,int h); void Move(int xOff,int yOff)23中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2

23、North University of China Location:Move(xOff,yOff); int GetX() return Location:GetX(); int GetY() return Location:GetY(); int GetH() return H; int GetW() return W;private: int W,H;void Rectangle:InitR(int x,int y,int w,int h) InitL(x,y); W=w; H=h;通过通过成员名限定符成员名限定符(:)指明调用基类中的成员指明调用基类中的成员24中北大学计算机系基础教研

24、室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaclass V:public Rectanglepublic: void Function();void V:Function() Move(3,2); 公有继承公有继承若继承方式为若继承方式为private,Move(3,2)是否正确是否正确?为什么为什么?若继承方式为若继承方式为private,Move(3,2)仍然仍然错误错误。原因原因:由于类:由于类Rectangle对类对类Location是

25、私有继承,是私有继承,而类而类V对类对类Rectangle是是直接继承直接继承,因此在类,因此在类V内内不不可以访问基类可以访问基类Location的公有成员的公有成员;错误调用错误调用25中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China 成员访问权限的控制成员访问权限的控制例例分析下列程序中的访问权限,并回答问题。分析下列程序中的访问权限,并回答问题。#include class Apublic: void f1();pr

26、otected: int j1;private: int i1;class B:public Apublic: void f2();protected: int j2;private: int i2;class C:public Bpublic: void f3();26中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China回答下列问题,并说明原因。回答下列问题,并说明原因。1、派生类、派生类B中成员函数中成员函数f2()能否访问

27、基类能否访问基类A中的成中的成员:员:f1()、j1和和i1?2、派生类、派生类B的对象的对象b1能否访问基类能否访问基类A中的成员:中的成员:f1()、j1和和i1?可以访问可以访问f1()和和j1,不可以访问不可以访问i1;可以访问可以访问f1(),不可以访问不可以访问j1和和i1;3、派生类、派生类C中的成员函数中的成员函数f3()能否访问直接基类能否访问直接基类B中的成员:中的成员:f2()、j2和和i2?能否访问间接基类能否访问间接基类A中的成员:中的成员: f1()、j1和和i1?可以访问直接基类中的可以访问直接基类中的f2()和和j2以及间接基类中以及间接基类中的的f1()和和j

28、1,不可以访问不可以访问i2和和i1;27中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China4、派生类、派生类C的对象的对象c1能否访问直接基类能否访问直接基类B中的成员:中的成员:f2()、j2和和i2?能否访问间接基类能否访问间接基类A中的成员:中的成员: f1()、j1和和i1?可以访问直接基类中的可以访问直接基类中的f2()以及间接基类中的以及间接基类中的f1(),其他都不可以访问;其他都不可以访问;28中北大学计算机

29、系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China派生类对象生成时,要调用构造函数进派生类对象生成时,要调用构造函数进行初始化。编译器的调用过程是先调用行初始化。编译器的调用过程是先调用基类的构造函数,对派生类中的基类数基类的构造函数,对派生类中的基类数据进行初始化,然后再调用派生类自己据进行初始化,然后再调用派生类自己的构造函数,对派生类的数据进行初始的构造函数,对派生类的数据进行初始化工作。析构函数的调用正好相反。化工作。析构函数的调用

30、正好相反。 4.3派生类的构造函数和析构函数派生类的构造函数和析构函数 构造构造和析构函数的访问和析构函数的访问29中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China基类子对象基类子对象:派生类的对象中由基类中说明的:派生类的对象中由基类中说明的数据成员和操作所构成的封装体;数据成员和操作所构成的封装体;基类子对象基类子对象由由基类基类中的中的构造函数构造函数进行进行初始化初始化;构造函数不能被继承;构造函数不能被继承;派生类

31、构造函数的工作:派生类构造函数的工作:k对自己的数据成员进行初始化;对自己的数据成员进行初始化;k负责调用基类构造函数使基类的数据成员得负责调用基类构造函数使基类的数据成员得以初始化;以初始化;k调用子对象的构造函数,对派生类中的子对调用子对象的构造函数,对派生类中的子对象进行初始化;象进行初始化; 一、派生类的构造函数一、派生类的构造函数30中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China派生类构造函数格式:派生类构造函数

32、格式:若某项的若某项的参数表为空参数表为空,则该项可从成员初始化列,则该项可从成员初始化列表中省略,表示使用表中省略,表示使用缺省构造函数缺省构造函数初始化该基类子初始化该基类子对象;对象;():(), ()说明:说明:31中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China#include class Apublic: A(int h,int w):he(h),we(w) A() couthe,weendl;private:

33、int he, we;class B:public Apublic: B(int h,int w,int h1,int w1,int l):A(h,w), obj1(h1,w1)len=l; B()coutlenendl; private: A obj1; int len; ;void main() B obj(1,2,3,4,5); 32中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China派生类构造函数调用顺序派生类构造函数调

34、用顺序:k基类的构造函数;基类的构造函数;k子对象的构造函数;子对象的构造函数;k派生类构造函数体;派生类构造函数体;33中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China 二、派生类的析构函数二、派生类的析构函数执行派生类的析构函数时,基类的析构函数也执行派生类的析构函数时,基类的析构函数也将被调用;将被调用;析构函数不能被继承;析构函数不能被继承;析构函数的执行顺序与构造函数严格析构函数的执行顺序与构造函数严格相反相反;k

35、派生类的析构函数;派生类的析构函数;k基类的析构函数;基类的析构函数;34中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China例例分析下列程序的输出结果。分析下列程序的输出结果。#include class Bpublic: B(); B(int i); B(); void Print() const;private: int b;B:B() b=0; coutBs default constructor called. end

36、l;35中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of ChinaB:B(int i) b=i; coutBs constructor called. endl; B:B() coutBs destructor called. endl;void B:Print() const coutbendl;class C:public B36中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研

37、室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinapublic: C(); C(int i,int j); C(); void Print() const; private: int c;C:C() c=0; coutCs default constructor called. endl;C:C(int i,int j):B(i) c=j;37中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North Un

38、iversity of China coutCs constructor called. endl;C:C() coutCs destructor called. endl;void C:Print() const B:Print(); coutcendl;void main() C obj(5,6); obj.Print();输出:输出:Bs constructor called.Cs constructor called.56Cs destructor called.Bs destructor called.38中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室

39、中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China三、派生类构造函数使用中应注意的问题三、派生类构造函数使用中应注意的问题派生类派生类构造函数的定义中可以构造函数的定义中可以省略省略对对基类构造基类构造函数函数的调用,其条件是在基类中必须有的调用,其条件是在基类中必须有缺省的缺省的构造函数构造函数或者根本或者根本没有定义没有定义任何任何构造函数构造函数;当基类的构造函数使用一个或多个参数时,派当基类的构造函数使用一个或多个参数时,派生类必须定义构造函数,提供将参数传递给基生类必须定义构造函数,提供将参数

40、传递给基类构造函数的途径;类构造函数的途径;编译器自动生成缺省构造函数编译器自动生成缺省构造函数设设基类基类数据成员为数据成员为m个,个,派生类派生类数据成员为数据成员为n个,个,派生类的派生类的参数参数个数为个数为x,则:则:0=x=m+n;39中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China4.4 多继承的概念多继承的概念class : , ;一、多继承派生类的声明形式:一、多继承派生类的声明形式:40中北大学计算机系基

41、础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China二、多继承的构造函数二、多继承的构造函数():(), () (),.多继承构造函数格式:多继承构造函数格式:41中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China二、多继承的构造函数二、多继承的构造函数(续续)派生类构造函数负责

42、所有基类构造函数的调用;派生类构造函数负责所有基类构造函数的调用;派生类构造函数执行顺序:派生类构造函数执行顺序:k执行所有基类的构造函数;执行所有基类的构造函数;k执行所有子对象的构造函数;执行所有子对象的构造函数;k执行派生类构造函数体;执行派生类构造函数体;处于同一层次的处于同一层次的各基类构造函数的执行顺序各基类构造函数的执行顺序取决取决于于定义派生类定义派生类时所指定的各基类时所指定的各基类顺序顺序,与派生类,与派生类构造函数中所定义的成员初始化列表中的各项顺构造函数中所定义的成员初始化列表中的各项顺序无关;序无关;42中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算

43、机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China例例分析下列程序的输出结果。分析下列程序的输出结果。#include class B1public: B1(int i) b1=i; coutConstructor B1. endl; void Print() coutb1endl;private: int b1;class B2public: B2(int i) b2=i; coutConstructor B2. endl; void Print() coutb2endl;43中北大学计

44、算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaprivate: int b2;class B3public: B3(int i) b3=i; coutConstructor B3. endl; int Getb3() return b3;private: int b3;class A:public B2,public B1public: A(int i,int j,int k,int l);多继承44中北大学计算机系基础教研室中北大

45、学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China void Print();private: int a; B3 bb;A:A(int i,int j,int k,int l):B1(i),B2(j),bb(k) a=l; coutConstructor A. endl; void A:Print() B1:Print(); B2:Print(); coutabb.Getb3()endl;子对象子对象基类构造函数调用顺序基类构造函数调用顺序与定义时的顺序不

46、同与定义时的顺序不同45中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinavoid main() A aa(1,2,3,4); aa.Print();输输出出Constructor B2.Constructor B1.Constructor B3.Constructor A.124 346中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计

47、算机系基础教研室 2013-2North University of China三、二义性问题三、二义性问题1、产生二义性的原因、产生二义性的原因在在多继承多继承情况下,造成的对情况下,造成的对基类基类中中某个成员某个成员的的访问访问出现的出现的不唯一不唯一的情况;的情况;class Aclass C:public A,public B public: public: void f(); void g(); void h();class B ;public: void f(); void g();void f();c1.f()A.f()B.f()C47中北大学计算机系基础教研室中北大学计算机系

48、基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China三、二义性问题(续)三、二义性问题(续)问题:若定义问题:若定义C c1;,则则c1.f()是否正确?是否正确?答答:c1.f()将产生将产生二义性二义性;原因原因:不能识别是调用类不能识别是调用类A或类或类B的的f函数;函数;解决方法:解决方法:a.区别出是类区别出是类A或类或类B的的f函数;函数;c1.A:f();或或c1.B:f();b.在类中定义同名函数在类中定义同名函数f;当一个当一个派生类派生类从从多个基类

49、多个基类派生,而这些基类又派生,而这些基类又有一个有一个共同的基类共同的基类,则对该基类中说明的成员,则对该基类中说明的成员进行访问时,可能会出现二义性;进行访问时,可能会出现二义性;48中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China三、二义性问题(续)三、二义性问题(续)class Aclass B2:public A public: private: int a; int b2; ;class B1:public Ac

50、lass C:public B1,public B2 private: public: int b1; int f(); private: int c; ;c1.aA.aB1.b1CB2.b2A.a49中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China三、二义性问题(续)三、二义性问题(续)问题:若定义问题:若定义C c1;,则则c1.a与与c1.A:a是否正确?是否正确?答答:c1.a与与c1.A:a将产生将产生二义性二义性

51、;原因原因:不能识别是通过类不能识别是通过类B1或类或类B2调用类调用类A的的a;解决方法:解决方法:a.区别出是通过类区别出是通过类B1或类或类B2调用类调用类A的的a;c1.B1:a;或或c1.B2:a;b.在类中定义一个同名成员;在类中定义一个同名成员;2、解决方法、解决方法利用成员名限定法消除二义性;利用成员名限定法消除二义性;在类中定义一个同名成员;在类中定义一个同名成员;虚基类;虚基类;50中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North Univer

52、sity of China例例分析下列程序的输出结果分析下列程序的输出结果。 #include class A public: A(int i) a=i; coutConstructor A. iendl; A() coutDestructor A. endl; void Print() coutaendl; private: int a; ; class B1:public A public: B1(int i,int j):A(i) b1=j; coutConstructor B1. endl; 51中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算

53、机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China B1() coutDestructor B1. endl; void Print() A:Print(); coutb1endl; private: int b1;class B2:public Apublic: B2(int i,int j):A(i) b2=j; coutConstructor B2. endl; B2() coutDestructor B2. endl; void Print() A:Print();coutb2endl; private:

54、int b2;52中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaclass C:public B1,public B2public: C(int i,int j,int k,int l,int m):B1(i,j),B2(k,l),c(m) coutConstructor C. endl; C() coutDestructor C. endl; void Print() B1:Print(); B2:Print(); co

55、utcendl; private: int c;void main() C c1(1,2,3,4,5); c1.Print();53中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of ChinaConstructor A.1Constructor B1. Constructor A.3Constructor B2.Constructor C.12345Destructor C.Destructor B2.Destructor A.Dest

56、ructor B1.Destructor A.执执行行结结果果54中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of China4.5虚基类的引入和说明虚基类的引入和说明引入目的:引入目的:解决二义性问题,在继承间接共同解决二义性问题,在继承间接共同基类时只保留一份成员基类时只保留一份成员格式:格式:virtual 说明:说明:关键字关键字virtual与关键字与关键字public或或private的相对的相对位置无关,但必须位于虚基类名

57、之前,且位置无关,但必须位于虚基类名之前,且virtual只只对紧随其后的基类名起作用;对紧随其后的基类名起作用;例如:例如:class D:virtual public A,private B,virutal public C其中:类其中:类A和类和类C是是虚基类虚基类,而类,而类B是是非虚基类非虚基类;55中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室中北大学计算机系基础教研室 2013-2North University of Chinaclass Apublic: void f();protected: int a;class B:virtual public Aprotected: int b;class

温馨提示

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

评论

0/150

提交评论