c程序设计基础第八章继承和派生英语

上传人:M****1 文档编号:592645517 上传时间:2024-09-21 格式:PPT 页数:106 大小:1.46MB
返回 下载 相关 举报
c程序设计基础第八章继承和派生英语_第1页
第1页 / 共106页
c程序设计基础第八章继承和派生英语_第2页
第2页 / 共106页
c程序设计基础第八章继承和派生英语_第3页
第3页 / 共106页
c程序设计基础第八章继承和派生英语_第4页
第4页 / 共106页
c程序设计基础第八章继承和派生英语_第5页
第5页 / 共106页
点击查看更多>>
资源描述

《c程序设计基础第八章继承和派生英语》由会员分享,可在线阅读,更多相关《c程序设计基础第八章继承和派生英语(106页珍藏版)》请在金锄头文库上搜索。

1、C+程序设计基础程序设计基础第第8章章 继承与派生继承与派生北京邮电大学信通院北京邮电大学信通院方莉方莉第第8 8章章 继承与派生继承与派生v类类具有具有封装性、继承性和多态性封装性、继承性和多态性,使得软件开发,使得软件开发者可以把类设计成相对独立的模块,像一个个积者可以把类设计成相对独立的模块,像一个个积木块,便于重用。木块,便于重用。v类的继承性类的继承性是实现是实现软件重用软件重用的一种重要形式。的一种重要形式。v本章将学习:本章将学习:继承和派生的概念,继承方式;继承和派生的概念,继承方式;派生类的构造函数和析构函数;派生类的构造函数和析构函数;2第第8 8章章 继承与派生继承与派生

2、8.1 8.1 继承的概念继承的概念8.2 8.2 定义基类和派生类定义基类和派生类8.3 8.3 构造函数和析构函数构造函数和析构函数8.4 8.4 转换与继承转换与继承38.1 8.1 继承的概念继承的概念- -例子例子自行车自行车Bicycle山地车山地车 Mountain Bike竞速自行车竞速自行车 Racing Bike双人自行车双人自行车 Tandem Bike48.1 8.1 继承的概念继承的概念- -例子例子v山地车山地车继承继承了自行车的特征了自行车的特征山地车山地车 “派生派生”于于 自行车自行车58.1 8.1 继承的概念继承的概念 v类的继承类的继承是在现有类的基础之

3、上,创建新类的机制是在现有类的基础之上,创建新类的机制。称现有的类为称现有的类为基类基类,新建立的类为新建立的类为派生类派生类。派生类继承了基类的属性和行为派生类继承了基类的属性和行为派生类是基类的特殊情况。派生类是基类的特殊情况。v基类是基类是共性的抽象共性的抽象,派生类是,派生类是个性的体现个性的体现。v不必从不必从“草稿草稿”开始创建特殊的程序对象。开始创建特殊的程序对象。v继承是处理继承是处理“特殊情况特殊情况”的面向对象编程机制。的面向对象编程机制。 6Bike基类Tandem Bike派生类派生于int Wheel;bool Run();int Wheel;bool Run();i

4、nt Seat;父类子类 从基类继承8.1 8.1 继承的概念继承的概念 7第第8 8章章 继承与派生继承与派生8.1 8.1 继承的概念继承的概念8.2 8.2 定义基类和派生类定义基类和派生类8.3 8.3 构造函数和析构函数构造函数和析构函数8.4 8.4 转换与继承转换与继承88.2 8.2 定义基类和派生类定义基类和派生类v定义派生类时要声明继承方式定义派生类时要声明继承方式,三种继承方式:,三种继承方式:publicpublicProtectedProtectedprivate private v访问控制受继承方式的影响;访问控制受继承方式的影响;v不同继承方式的影响主要体现在:不

5、同继承方式的影响主要体现在: 派生类成员对基类成员的访问控制;派生类成员对基类成员的访问控制; 派生类对象对基类成员的访问控制;派生类对象对基类成员的访问控制;v继承导致一种特殊的语法现象:继承导致一种特殊的语法现象:同名覆盖同名覆盖。98.2.1 8.2.1 简单的继承和派生简单的继承和派生v问题:想在屏幕上画出正三角形、矩形或圆形问题:想在屏幕上画出正三角形、矩形或圆形v方法一:结构化方法方法一:结构化方法DrawTriDrawTri ( (intint x, x, intint y, char color, y, char color, intint side); side);DrawR

6、ectDrawRect ( (intint x, x, intint y, char color, y, char color, intint length, length, intint width) width)DrawCircle(intDrawCircle(int x, x, intint y, char color, y, char color, intint Radius) Radius)v方法二:面向对象?方法二:面向对象?class circle class circle 圆形圆形class rectangle class rectangle 矩形矩形class triangl

7、e class triangle 三角形三角形基类:基类: class shapeclass shape色彩色彩 colorcolor位置位置 (x, y)(x, y)shapecirclerectangletriangle泛化?10v图形图形circle circle 圆形圆形rectangle rectangle 矩形矩形triangle triangle 三角形三角形 基类称为基类称为父类父类派生类称为派生类称为子类子类 shapecirclerectangletrianglev分层次的设计类使模块划分更合分层次的设计类使模块划分更合理;便于软件系统的设计和维护理;便于软件系统的设计和维

8、护。8.2.1 8.2.1 简单的继承和派生简单的继承和派生11class Shapeprivate: int m_x,m_y; /位置位置 char m_color; /颜色颜色public: Shape(); void setposition(int x, int y); void setcolor(char color); int getx(); int gety(); char getcolor();例例1-1-定义基类定义基类shapeshape成员函数的分类:成员函数的分类:1.构造函数构造函数2.设置属性值设置属性值3.读取属性值读取属性值12class Triangle: pu

9、blic Shape public:Triangle(int x, int y, char color=R, float slen = 1);float GetSideLength() const;void SetTriangle(int x, int y, char color, float slen);void Draw();private:float m_SideLength;例例1-1-定义派生类定义派生类( (等边三角形等边三角形类类) )成员函数的分类:成员函数的分类:1.构造函数构造函数2.设置属性值设置属性值3.读取属性值读取属性值13派生类的定义格式派生类的定义格式class

10、 class 派生类名:派生类名:继承方式继承方式 基类名基类名 public: public: / /派生类公有成员派生类公有成员 private:private: / /派生类私有成员派生类私有成员 派生类派生类只有只有一个直接基一个直接基类类为为单继承单继承8.2.2 8.2.2 定义派生类定义派生类14 class 派生类名:派生类名:继承方式继承方式 基类名基类名1, 继承方式继承方式 基类名基类名n public: /派生类公有成员派生类公有成员 private: /派生类私有成员派生类私有成员 有多个基类有多个基类派生类有派生类有多个基类多个基类为为多继承多继承8.2.2 8.2

11、.2 定义派生类定义派生类15u例如例如: : 已有基类已有基类b1b1和和b2b2,定义派生类定义派生类derivederive,其中包括:,其中包括:u私有整型成员私有整型成员 newIntnewInt,u公有函数成员公有函数成员 intint newFunnewFun()(),u私有函数成员私有函数成员 intint max(intmax(int a, a, intint b) b);u写出类写出类derivederive的定义的定义8.2.2 8.2.2 定义派生类定义派生类class derive : public b1 , private b2private: int newInt

12、;public: void newFun();private:int max( int a, int b );16v类的继承方式是类的继承方式是派生类对基类成员的继承方式派生类对基类成员的继承方式。v类类的的继继承承方方式式影影响响类类外外模模块块对对于于派派生生类类从从基基类类继继承承来来的的成成员员的的访问权限访问权限。v每一个每一个“继承方式继承方式”,只用于限制对,只用于限制对紧随其后紧随其后之基类的继承。之基类的继承。class derive : public b1 , private b2private: int newInt;public: void newFun();priva

13、te:int max( int a, int b );8.2.2 8.2.2 定义派生类定义派生类17class base ;class deriver1:public base ;class deriver2:public deriver1 父类被称为子类的父类被称为子类的直直接基类接基类 父类的父类或更高层父类的父类或更高层次的父类被称为这个次的父类被称为这个子类的子类的间接基类间接基类 8.2.2 8.2.2 定义派生类定义派生类18class Shape:public:Shape(int x=0, int y=0, char c = R);int GetX() const;void S

14、etX( int x);int GetY() const;void SetY( int x);char GetColor() const;void SetColor(char c);protected:char m_color;int m_x;int m_y; ;例例2-2-图形类及其派生类的声明图形类及其派生类的声明19class Circle : public Shape public:Circle(int x, int y, float r=1, char color=R);void SetCircle(int x, int y, float r, char color); float

15、GetRadius () const; void Draw();private:float m_Radius;例例2-2-图形类及其派生类的声明图形类及其派生类的声明20class Triangle: public Shape public:Triangle(int x, int y, char color=R, float slen = 1);void SetTriangle(int x, int y, char color, float slen);float GetSideLength() const; void Draw();private:float m_SideLength;例例2

16、-2-图形类及其派生类的声明图形类及其派生类的声明21class Rectangle: public Shapepublic:Rectangle(int x, int y, char color, int length=10, int width=10);void SetRectangle (int x, int y, char color, int length, int width); int GetWidth() const;int GetHeight() const;void Draw();private:int m_Width;int m_Length;例例2-2-图形类及其派生类的

17、声明图形类及其派生类的声明22派生类的成员包括:(派生类的成员包括:(1 1)继承基)继承基类的成员,(类的成员,(2 2)派生类定义时声)派生类定义时声明的成员。明的成员。派生类自己增加的成员,完成两个派生类自己增加的成员,完成两个需求:需求:(1)(1)修改基类成员,(修改基类成员,(2 2)描)描述新的特征或方法。述新的特征或方法。 m_color;m_x; m_y;GetX();SetX();GetY();SetY();GetColor();SetColor();m_Radius;GetRadius () SetCircle();Draw(); 从基从基类类继承的继承的成员成员派生类派

18、生类增加的增加的成员成员238.2.3 8.2.3 访问控制和继承关系访问控制和继承关系v类成员的可见性类成员的可见性公共成员:公共成员:publicpublic保护成员:保护成员:protectedprotected私有成员:私有成员:privateprivatev继承的方式继承的方式公有继承公有继承(public)(public)保护继承保护继承(protected)(protected)私有继承私有继承(private)(private)v派生类继承了基类中的所有成员,派生类继承了基类中的所有成员,但不包括但不包括构造函数构造函数析构函数析构函数248.2.3 8.2.3 访问控制和继承

19、关系访问控制和继承关系v不同继承方式决定的不同访问控制权限体现在:不同继承方式决定的不同访问控制权限体现在:派生类的派生类的成员函数成员函数对其继承的基类成员的对其继承的基类成员的访问控制访问控制;其其它它模模块块通通过过派派生生类类对对象象对对其其继继承承的的基基类类成成员员的的访访问问控控制。制。private:protected:public:基类?派生类publicprotectedprivate继承方式决定继承成员的访问权限继承来的成员的访问权限?251. 1. 公有继承公有继承 公有继承的派生类定义形式:公有继承的派生类定义形式: class class 派生类名:派生类名:pub

20、licpublic 基类名基类名 派生类新成员定义;派生类新成员定义; ; ;private:protected:public:基类?派生类1.基类成员基类成员 在派生类中的访问属性不变。2.派生类的成员函数派生类的成员函数 可以访问基类的公有成员和保护成员,不能访问基类的私有成员;3.派生类以外的其它函数派生类以外的其它函数 可以通过派生类的对象,访问从基类继承的公有成员, 但不能访问从基类继承的保护成员和私有成员。privateprotectedpublic派生类成员函数可以访问派生类对象基类成员的属性public26vpublicpublic是定义公有继承方式的关键字。是定义公有继承方式

21、的关键字。v公有继承方式定义的派生类,继承了基类中公有继承方式定义的派生类,继承了基类中除构造函数和析除构造函数和析构函数构函数外的其余成员:公有成员、保护成员和私有成员外的其余成员:公有成员、保护成员和私有成员v被继承的基类成员在派生类中仍将被继承的基类成员在派生类中仍将保持保持其其原来的访问属性原来的访问属性。v派生类的派生类的成员函数成员函数可以访问基类的公有成员和保护成员,可以访问基类的公有成员和保护成员,不不能能访问基类的访问基类的私有成员私有成员; ;v派生类以外的其它函数可以通过派生类的对象,访问从基类派生类以外的其它函数可以通过派生类的对象,访问从基类继承的公有成员继承的公有成

22、员, , 但但不能不能访问从基类继承的访问从基类继承的保护成员和私有保护成员和私有成员成员。 8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系27class 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;8.

23、2.3 8.2.3 访问控制和继承关系访问控制和继承关系28class Rectangle: public 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,H;l派生类中的派生类中的 成员函成员函数数 可以直接访问基类可以直

24、接访问基类中的中的publicpublic和和protectedprotected成员成员,但不,但不能访问基类的能访问基类的privateprivate成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系29main() Rectangle rect; coutrect.X; /? coutrect.GetX();/?l使用派生类的使用派生类的 对象对象 只只能访问基类的能访问基类的publicpublic成员成员8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系错误错误正确正确30class Rectangle: public Point/派生类声明部分派生类

25、声明部分public:/新增公有函数成员新增公有函数成员void InitR(float x, float y, float w, float h)X=x; Y=y; /?访问基类私有成员访问基类私有成员 W=w;H=h;float GetH() return H;float GetW() return W;private:/新增私有数据成员新增私有数据成员float W,H;l派生类中的派生类中的 成员函数成员函数 可以可以直接访问基类中的直接访问基类中的public和和protected成员,但成员,但不能不能访问访问基类的基类的private成员成员。8.2.3 8.2.3 访问控制和继

26、承关系访问控制和继承关系错误错误31class 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;protected:float X,Y;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系32class Rectangle: public Point/派生类声明部分派生类声明部分public:/新增公

27、有函数成员新增公有函数成员void InitR(float x, float y, float w, float h)X=x; Y=y; /?访问基类的保护成员访问基类的保护成员 W=w;H=h;float GetH() return H;float GetW() return W;private:/新增私有数据成员新增私有数据成员float W,H;l派生类中的派生类中的 成员函成员函数数 可以直接访问基类可以直接访问基类中的中的public和和protected成员,但不能访问基成员,但不能访问基类的类的private成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系

28、正确正确33main() Rectangle rect; coutrect.X; /? coutrect.GetX();/?l使用派生类的使用派生类的 对象对象 只能只能访问基类的访问基类的publicpublic成员成员依然错误依然错误! !8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系正确正确342. 2. 私有继承私有继承 私有继承的派生类定义形式:私有继承的派生类定义形式: class class 派生类名:派生类名:private private 基类名基类名 派生类新成员定义;派生类新成员定义; ; ;private:protected:public:基类?派生类1.

29、基类成员基类成员:在派生类中的访问属性都变成在派生类中的访问属性都变成 private。2.派生类的成员函数派生类的成员函数: 可以访问基类的公有成员和保护成员,不能访问基可以访问基类的公有成员和保护成员,不能访问基类的私有成员类的私有成员;3.派生类以外的其它函数派生类以外的其它函数:不能通过派生类的对象,访问从基类继承的任何不能通过派生类的对象,访问从基类继承的任何成员。成员。privateprivateprivate派生类成员函数可以访问基类成员的属性private派生类对象35vprivateprivate是定义私有继承方式的关键字是定义私有继承方式的关键字v以以私有继承方式私有继承方

30、式定义的派生类,继承了基类中可以继承的成定义的派生类,继承了基类中可以继承的成员:公有成员、保护成员和私有成员,这些成员在派生类中的员:公有成员、保护成员和私有成员,这些成员在派生类中的访问属性都是访问属性都是私有的私有的。v派生类的成员函数派生类的成员函数可以访问基类的公有成员和保护成员,可以访问基类的公有成员和保护成员,不不能访问能访问基类的基类的私有成员私有成员。v派生类以外的其它函数派生类以外的其它函数则则不能不能通过派生类的对象通过派生类的对象访问从基类访问从基类继承的任何成员继承的任何成员。 8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系36class Point /

31、基类声明基类声明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;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系37class Rectangle: private Point/派生类声明派生类声明public:/新增外部接口新增外部接口void InitR(float x, float y, f

32、loat 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;派生类中的派生类中的 成员函数成员函数 可以直接访问基类中可以直接访问基类中的的pub

33、licpublic和和protectedprotected成员,但成员,但不能访问基不能访问基类的类的privateprivate成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系正确正确38class Rectangle: private Point/派生类声明派生类声明public:/新增外部接口新增外部接口void InitR(float x, float y, float w, float h) X=x; Y=y;/? W=w;H=h; void Move(float xOff, float yOff) Point:Move(xOff,yOff);float Ge

34、tX() return Point:GetX();float GetY() return Point:GetY();float GetH() return H;float GetW() return W;private:/新增私有数据新增私有数据float W,H;派生类中的派生类中的 成员函数成员函数 可以直接访问基类中的可以直接访问基类中的publicpublic和和protectedprotected成成员,员,但不能访问基类的但不能访问基类的privateprivate成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系错误错误39class Point/基类声明基

35、类声明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;protected: float X,Y;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系40class Rectangle: private Point/派生类声明派生类声明public:/新增外部接口新增外部接口void InitR(float x, float y, floa

36、t w, float h) X=x; Y=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;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系正确正确41main() Rectangle rect; coutrect.

37、X; /? coutrect.GetX();/?l使用派生类的使用派生类的 对象对象 不不能访问基类中的任何成员能访问基类中的任何成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系错误错误错误错误423. 3. 保护继承保护继承 保护继承的派生类定义形式:保护继承的派生类定义形式: class class 派生类名:派生类名:protectedprotected 基类基类名名 派生类新成员定义;派生类新成员定义; ; ;private:protected:public:基类?派生类1.基类成员:基类成员:公有成员和保护成员在派生类中变成保护类型的,基类的私公有成员和保护成员在派

38、生类中变成保护类型的,基类的私有成员属性不变。有成员属性不变。2.派生类的成员函数派生类的成员函数:可以访问基类的公有成员和保护成员,不能访问基可以访问基类的公有成员和保护成员,不能访问基类的私有成员类的私有成员;3.派生类以外的其它函数派生类以外的其它函数:不能通过派生类的对象,访问从基类继承的任不能通过派生类的对象,访问从基类继承的任何成员。何成员。privateprotectedprotected派生类成员函数可以访问基类成员的属性prot-ected派生类对象43vprotectedprotected是定义保护继承方式的关键字是定义保护继承方式的关键字v以以保护继承方式保护继承方式定义

39、的派生类,继承了基类中可以继承的成定义的派生类,继承了基类中可以继承的成员:公有成员、保护成员和私有成员。其中基类的员:公有成员、保护成员和私有成员。其中基类的公有成员公有成员和保护成员和保护成员在派生类中访问控制属性变成在派生类中访问控制属性变成保护类型的保护类型的,基类,基类的的私有成员私有成员保持保持原来属性原来属性。v派生类的成员函数派生类的成员函数可以访问基类的公有成员和保护成员,可以访问基类的公有成员和保护成员,不不能访问能访问基类的基类的私有成员私有成员。v派生类以外的其它函数派生类以外的其它函数则则不能不能通过派生类的对象通过派生类的对象访问访问从基类从基类继承的继承的任何成员

40、任何成员。 8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系44class 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;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系45class Rectangle: protected Point/派生类声明派生

41、类声明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:/新增私有数据新增私有数据f

42、loat W,H;派生类中的派生类中的 成员函数成员函数 可以直接访问基类中可以直接访问基类中的的publicpublic和和protectedprotected成员,成员,但不能访问基但不能访问基类的类的privateprivate成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系正确正确46class Rectangle: protected Point /派生类声明派生类声明public: /新增外部接口新增外部接口void InitR(float x, float y, float w, float h) X=x; Y=y;/? W=w;H=h; void Mov

43、e(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;派生类中的派生类中的 成员函数成员函数 可以直接访问基类中的可以直接访问基类中的publicpublic和和protectedprotected成成员,员,但不能访问基类的但不能访问基类的privateprivate成员

44、。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系错误错误47class 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;protected: float X,Y;8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系48class Rectangle: protected Point /派生

45、类声明派生类声明public: /新增外部接口新增外部接口void InitR(float x, float y, float w, float h) X=x; Y=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;派生类中的

46、派生类中的 成员函数成员函数 可以直接访问基类中的可以直接访问基类中的publicpublic和和protectedprotected成成员,员,但不能访问基类的但不能访问基类的privateprivate成员。成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系正确正确49main() Rectangle rect; coutrect.X; /? coutrect.GetX();/?l使用派生类的使用派生类的 对象对象 不能访问基类中的任不能访问基类中的任何成员。何成员。8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系错误错误错误错误50私有继承和保护继承的区别私有

47、继承和保护继承的区别private:protected:public:父类privateprotectedprotected子类protectedprivate:protected:public:父类privateprivateprivate:子类privateprivateprivateprivate:孙类privateprotectedpublic孙类成员函数无法访问孙类成员函数无法访问protectedpublicprivateprotectedprotected孙类孙类成员函数可以访问孙类成员函数可以访问51public:protected:private:publicpublicpr

48、otectedprivateprotectedprotectedprotectedprivateprivateprivateprivateprivate基类存取方式继承类型派生类继承的基类成员的访问属性8.2.3 8.2.3 访问控制和继承关系访问控制和继承关系52v派生类派生类修改修改基类的成员,是在派生类中声明了一个基类的成员,是在派生类中声明了一个与基类成员与基类成员同名同名的新成员的新成员。v在派生类作用域内或者在类外通过派生类的对象直在派生类作用域内或者在类外通过派生类的对象直接使用这个成员名,只能访问到派生类中声明的同接使用这个成员名,只能访问到派生类中声明的同名新成员,这个新成员

49、覆盖了从基类继承的同名成名新成员,这个新成员覆盖了从基类继承的同名成员,这种情况称为员,这种情况称为同名覆盖同名覆盖。 8.2.4 8.2.4 同名覆盖同名覆盖53class base public: void f () coutbaseendl; ;class deriver: public base public: void f () coutderiverendl; ;int main( ) deriver derobj; derobj.f (); return 0;输出结果输出结果?A: baseB: deriver在在派生类中声明了一个中声明了一个与基类成员同名的新成员的新成员O O

50、v ve er rR Ri id de e只能访问到派生类只能访问到派生类中的同名新成中的同名新成员员在派生类作用域内派生类作用域内或者在类外类外通过派生类的对象直接使用这个成员名8.2.4 8.2.4 同名覆盖同名覆盖54同名覆盖示例同名覆盖示例 #includeusing namespace std;class base public: void function()coutfunction of class baseendl; ;class deriver: public base public: void function()coutfunction of class derivere

51、ndl; ;v同名的新成员。同名的新成员。v同名覆盖。同名覆盖。55void main() deriver derobj; derobj.function();输出结果输出结果:function of class deriver同名覆盖示例同名覆盖示例 56第第8 8章章 继承与派生继承与派生8.1 8.1 继承的概念继承的概念8.2 8.2 定义基类和派生类定义基类和派生类8.3 8.3 构造函数和析构函数构造函数和析构函数8.4 8.4 转换与继承转换与继承578.3 8.3 派生类构造函数和析构函数派生类构造函数和析构函数v派派生生类类继继承承了了基基类类中中除除构构造造函函数数和和析析

52、构构函函数数之之外外的的所有成员。所有成员。v基类的构造函数和析构函数不能被派生类所继承基类的构造函数和析构函数不能被派生类所继承; ;v派生类一般需要定义自己的构造函数和析构函数派生类一般需要定义自己的构造函数和析构函数; ;v派生类的构造及析构函数通常会受到基类构造及析派生类的构造及析构函数通常会受到基类构造及析构函数的影响。构函数的影响。588.3.1 8.3.1 基类只有基类只有无参数无参数的构造函数的构造函数v在基类具有在基类具有无参构造函数无参构造函数,派生类又,派生类又没有定义构造没有定义构造函数函数的时候,系统会的时候,系统会自动的调用基类无参构造函数自动的调用基类无参构造函数

53、,来构造派生类对象中的基类成分。来构造派生类对象中的基类成分。59#includeusing namespace std;class base private: int m_data;public: void SetData(int data)m_data=data; int GetData()return m_data;使用系统提供的默认构造函数使用系统提供的默认构造函数60class deriver:public baseprivate: int m_member;public: void SetMember(int m) m_member=m; int GetMember()return

54、 m_member;使用系统提供的默认构造函数使用系统提供的默认构造函数61void main() int n(10); deriver obj; obj.SetMember(n); coutobj.GetMember()endl;输出结果:输出结果:10使用系统提供的默认构造函数使用系统提供的默认构造函数628.3.1 8.3.1 基类只有基类只有无参数无参数的构造函数的构造函数v如果基类如果基类没有无参没有无参构造函数,派生类也构造函数,派生类也不定义不定义自己自己的构造函数,在的构造函数,在编译编译的时候,一定会的时候,一定会有语法错误有语法错误。63v如果基类和对象数据成员的如果基类和

55、对象数据成员的构造函数都无参数构造函数都无参数,派生类构造函数派生类构造函数形参表中将形参表中将只包含只包含用于初始化它用于初始化它自己的自己的基本类型数据成员的参数基本类型数据成员的参数。v如果这个如果这个派生类派生类恰好恰好没有没有基本类型的数据成员,基本类型的数据成员,则其构造函数的形参表为空,则其构造函数的形参表为空,可以不定义构造函可以不定义构造函数,而使用系统提供的默认构造函数。数,而使用系统提供的默认构造函数。 8.3.1 8.3.1 基类只有无参数的构造函数基类只有无参数的构造函数648 8.3.3.2 .2 派生类的构造函数派生类的构造函数v不参与继承的特殊函数不参与继承的特

56、殊函数构造函数构造函数析构函数析构函数作为特权地位的友元函数作为特权地位的友元函数赋值运算符函数赋值运算符函数v派生类需要自己定义的构造函数和析构函数。派生类需要自己定义的构造函数和析构函数。65v基类的构造函数不被继承,需要在派生类中自行定基类的构造函数不被继承,需要在派生类中自行定义义 。v派生类的构造函数完成:派生类的构造函数完成:初始化本类的数据成员;初始化本类的数据成员;完成派生类中基类成分的初始化:通过调用基类的构造完成派生类中基类成分的初始化:通过调用基类的构造函数,并为基类的构造函数传递参数;函数,并为基类的构造函数传递参数;如果数据成员有对象,则需调用对象成员的构造函数;如果

57、数据成员有对象,则需调用对象成员的构造函数;8 8.3.3.2 .2 派生类的构造函数派生类的构造函数66v派生类的构造函数:派生类的构造函数:构造函数构造函数参数表参数表中以中以合适的初值为参数,初始化本类中合适的初值为参数,初始化本类中新增成员。新增成员。利用利用成员初始化表成员初始化表隐含调用隐含调用基类基类和和新增对象数据成员新增对象数据成员的的构造函数,初始化它们各自的数据成员。构造函数,初始化它们各自的数据成员。v构造函数的调用次序构造函数的调用次序系统会使用系统会使用派生类构造函数的形参表的参数派生类构造函数的形参表的参数调用调用基类基类和和内嵌对象成员的构造函数内嵌对象成员的构

58、造函数。 8 8.3.3.2 .2 派生类的构造函数派生类的构造函数67v派生类构造函数的一般形式派生类构造函数的一般形式: : 派派生生类类名名:派派生生类类名名( (基基类类所所需需的的形形参参,本本类类成成员员所所需的形参需的形参) ): :基类基类1(1(基类参数表基类参数表1), ,1), ,基类基类n(n(基类参数表基类参数表n),n),对对象象成成员员1(1(对对象象参参数数表表1), 1), ,对对象象成成员员m(m(对对象象参参数数表表m)m) 本类基本类型数据成员初始化;本类基本类型数据成员初始化; 8.3.2 8.3.2 派生类构造函数派生类构造函数初始化列表68v单继承

59、时的构造函数单继承时的构造函数 派生类名派生类名:派生类名派生类名( (基类所需的形参,本类成员所需的形参基类所需的形参,本类成员所需的形参) ): :基类名基类名( (参数参数) ) 本类成员初始化赋值语句;本类成员初始化赋值语句; 8.3.2 8.3.2 派生类构造函数派生类构造函数69例例8-4 8-4 单继承派生类构造函数单继承派生类构造函数70v多文件结构:多文件结构:主函数:主函数:ch8_4_main().cppch8_4_main().cpp类类TShapeTShape的声明:的声明:TShape04.hTShape04.h类类TShapeTShape的实现:的实现:TShap

60、e04.cppTShape04.cpp类类TEllipseTEllipse的声明:的声明:TEllipse04.hTEllipse04.h类类TEllipseTEllipse的实现:的实现:TEllipse04.cppTEllipse04.cpp例例8-4 8-4 单继承派生类构造函数单继承派生类构造函数71/TShape04.cpp/TShape04.cpp#include TShape04.h#include TShape04.h#include #include TShape:TShape(uintTShape:TShape(uint x, x, uintuint y) y) _x =

61、x; _x = x; _y = y; _y = y; void void TShape:DrawTShape:Draw()() std:coutstd:coutThis is This is TShape:DrawTShape:Draw()()std:endlstd:endl; ; void void TShape:getXY(uintTShape:getXY(uint& x, & x, uintuint& y)& y) x = _x; x = _x; y = _y; y = _y; void void TShape:getRGB(ucharTShape:getRGB(uchar& R, &

62、R, ucharuchar& G, & G, ucharuchar& B)& B) R = _RED; R = _RED; G = _GREEN; G = _GREEN; B = _BLUE; B = _BLUE; void void TShape:setXY(uintTShape:setXY(uint x, x, uintuint y) y) _x = x; _x = x; _y = y; _y = y; void void TShape:setRGB(ucharTShape:setRGB(uchar R, R, ucharuchar G, G, ucharuchar B) B) _RED=

63、R; _RED=R; _GREEN=G; _GREEN=G; _BLUE=B; _BLUE=B; /TShape04.h/TShape04.htypedeftypedef unsigned unsigned intint uintuint; ;typedeftypedef unsigned char unsigned char ucharuchar; ;class class TShapeTShape private:private: uintuint _x, _y; / _x, _y; /几何形状的位置几何形状的位置protected:protected: /* /*声明几何形状的颜色。允许

64、声明几何形状的颜色。允许TShapeTShape的派生的派生类直接访问这些颜色属性,而不允许在类外类直接访问这些颜色属性,而不允许在类外通过类的对象直接访问这些属性通过类的对象直接访问这些属性 * */ / ucharuchar _RED, _GREEN, _BLUE; _RED, _GREEN, _BLUE;public:public: TShape(uintTShape(uint x, x, uintuint y); y); void void getXY(uintgetXY(uint& x, & x, uintuint& y);& y); void void setXY(uintsetX

65、Y(uint x, x, uintuint y); y); void Draw(); void Draw(); void void getRGB(uchargetRGB(uchar& R, & R, ucharuchar& G, & G, ucharuchar& B);& B); void void setRGB(ucharsetRGB(uchar R, R, ucharuchar G, G, ucharuchar B);B);例例8-4 8-4 单继承派生类构造函数单继承派生类构造函数72/TEllipse04.cpp/TEllipse04.cpp#include TEllipse04.h#

66、include TEllipse04.h#include #include TEllipse:TEllipse(uintTEllipse:TEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y):TShape(x,yy):TShape(x,y) _ _longRlongR = = longRlongR; ; _ _shortRshortR = = shortRshortR; ; / /在派生类构造函数中初始化基类保护成员在派生类构造函数中初始化基类保护成员 _RED = 0x00; _RED

67、= 0x00; _GREEN = 0x00; _GREEN = 0x00; _BLUE = 0x00; _BLUE = 0x00; TEllipse:TEllipseTEllipse:TEllipse()() void void TEllipse:DrawTEllipse:Draw()() uintuint x, y; x, y; getXY(xgetXY(x, y); /, y); /调用基类函数获取椭圆的圆心坐标调用基类函数获取椭圆的圆心坐标 std:coutstd:coutDraw an ellipse with color(;Draw an ellipse with color(; s

68、td:coutstd:coutstatic_caststatic_cast (_RED) (_RED) , static_caststatic_cast (_GREEN)(_GREEN), static_caststatic_cast (_BLUE) (_BLUE) ) at point(;point(;/ / std:coutstd:cout_x,_y)_x,_y)std:endlstd:endl; /; /错误!在派错误!在派生类中不能访问基类私有成员生类中不能访问基类私有成员 std:coutstd:cout x, y) x, y)std:endlstd:endl; ; /TEllips

69、e04.h/TEllipse04.h#include TShape04.h#include TShape04.hclass class TEllipseTEllipse: public : public TShapeTShape protected:protected: uintuint _ _longRlongR, _, _shortRshortR; ;public:public: TEllipse(uintTEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y); y); TEllipse

70、TEllipse();(); void Draw(); void Draw(); void void getR(uintgetR(uint& & longRlongR, , uintuint& & shortRshortR);); void void setR(uintsetR(uint longRlongR, , uintuint shortRshortR););例例8-4 8-4 单继承派生类构造函数单继承派生类构造函数73/ch8_4_main.cpp/ch8_4_main.cpp#includeTEllipse04.h#includeTEllipse04.h#include#inclu

71、de using namespace std;using namespace std;void main()void main() TEllipseTEllipse elps(10u,5u,20u,30u); elps(10u,5u,20u,30u); elps.setRGB(0x00,0x00,0xff elps.setRGB(0x00,0x00,0xff);/);/调用基类的函数访问基调用基类的函数访问基类的保护成员类的保护成员 / / elps._REDelps._RED=0x10=0x10; ; / / 错误,不能通过派生类的对象错误,不能通过派生类的对象调用基类的私有成员调用基类的私

72、有成员 elps.Drawelps.Draw(); (); /调用派生类的调用派生类的DrawDraw函数函数 例例8-4 8-4 单继承派生类构造函数单继承派生类构造函数74派生类名派生类名:派生类名派生类名 ( (基类所需形参,本类成员所需形参基类所需形参,本类成员所需形参) ) : :基类基类1(1(基类参数表基类参数表1), 1), , ,基类基类n(n(基类参数表基类参数表n),n),对象成员对象成员1(1(对象参数表对象参数表1), 1), , ,对象成员对象成员m(m(对象参数表对象参数表m)m) 本类基本类型数据成员初始化;本类基本类型数据成员初始化; 初始化列表8.3.38.

73、3.3包含包含内嵌对象内嵌对象的派生类构造函数的派生类构造函数75v派生类的构造函数提供:派生类的构造函数提供:基类构造函数形参表所需的参数基类构造函数形参表所需的参数初始化派生类的内嵌对象数据成员所需的参数初始化派生类的内嵌对象数据成员所需的参数初始化派生类基本数据类型成员所需的参数初始化派生类基本数据类型成员所需的参数v将例将例8-48-4中的颜色抽取形成一个新类中的颜色抽取形成一个新类TColorTColor,用,用TColorTColor类的类的对象对象作为作为TShapeTShape类中的数据类中的数据成员成员,重,重新设计程序。新设计程序。8.3.38.3.3包含包含内嵌对象内嵌对

74、象的派生类构造函数的派生类构造函数76例例8-5 8-5 派生类的构造函数派生类的构造函数77v多文件结构:多文件结构:主函数:主函数:ch8_5_main().cppch8_5_main().cpp类类TColorTColor的声明:的声明:TColorTColor 05.h 05.h类类TColorTColor的实现:的实现: TColorTColor 05.cpp 05.cpp类类TShapeTShape的声明:的声明:TShape05.hTShape05.h类类TShapeTShape的实现:的实现:TShape05.cppTShape05.cpp类类TEllipseTEllipse的

75、声明:的声明:TEllipse05.hTEllipse05.h类类TEllipseTEllipse的实现:的实现:TEllipse05.cppTEllipse05.cpp头文件头文件GlobalType05.hGlobalType05.h例例8-5 8-5 派生类的构造函数派生类的构造函数78/TShape05.h/TShape05.h# #pragmapragma once once#include GlobalType05.h#include GlobalType05.h#include TColor05.h#include TColor05.hclass class TShapeTSha

76、pe private:private: uintuint _x, _y; / _x, _y; /几何形状的位置几何形状的位置protected:protected: TColorTColor _color; / _color; /颜色颜色public:public: TShape(uintTShape(uint x, x, uintuint y); y); TShape(uintTShape(uint x, x, uintuint y, y, TColorTColor color); color); TShapeTShape();(); void void getXY(uintgetXY(ui

77、nt& x, & x, uintuint& y) const;& y) const; void void setXY(uintsetXY(uint x, x, uintuint y); y); void Draw(); void Draw(); TColorTColor getColorgetColor() const;() const; void void setColor(TColorsetColor(TColor color); color);/ GlobalType05.h/ GlobalType05.h# #pragmapragma once / once /预处理指令,避免重复包含

78、本头预处理指令,避免重复包含本头文件文件typedeftypedef unsigned unsigned intint uintuint; ;typedeftypedef unsigned char unsigned char ucharuchar; ;/TColor05.h/TColor05.h# #pragmapragma once once#include GlobalType05.h#include GlobalType05.henumenum EColorComponentEColorComponent RED, GREEN, BLUE; RED, GREEN, BLUE;class

79、 class TColorTColor private:private: ucharuchar _RED, _GREEN, _BLUE; _RED, _GREEN, _BLUE;public:public: TColor(constTColor(const ucharuchar R=0x00, const R=0x00, const ucharuchar G=0x00, G=0x00, const const ucharuchar B=0x00); B=0x00);/普通构造函数普通构造函数 TColor(constTColor(const TColorTColor& color); & co

80、lor); /拷贝构造函数拷贝构造函数 TColorTColor& operator =(const & operator =(const TColorTColor& color);& color);/重载赋值运算符重载赋值运算符 void void setColor(ucharsetColor(uchar R, R, ucharuchar G, G, ucharuchar B); B); ucharuchar getComponent(EColorComponentgetComponent(EColorComponent component) const;component) const;例

81、例8-5 8-5 派生类的构造函数派生类的构造函数79/TColor05.cpp/TColor05.cpp#include TColor05.h#include TColor05.hTColor:TColor(ucharTColor:TColor(uchar R/* =0x00 */, R/* =0x00 */, /普通构造函数普通构造函数 ucharuchar G/* =0x00 */, G/* =0x00 */, ucharuchar B/* =0x00 */) B/* =0x00 */) _RED = R; _GREEN = G; _BLUE = B; _RED = R; _GREEN

82、= G; _BLUE = B; TColor:TColor(constTColor:TColor(const TColorTColor& color)& color)/拷贝构拷贝构造函数造函数 _RED = _RED = color._REDcolor._RED; ; _GREEN = _GREEN = color._GREENcolor._GREEN; ; _BLUE = _BLUE = color._BLUEcolor._BLUE; ; void void TColor:setColor(ucharTColor:setColor(uchar R, R, ucharuchar G, G, u

83、charuchar B) B) _RED = R; _GREEN = G; _BLUE = B; _RED = R; _GREEN = G; _BLUE = B; /TEllipse.hTEllipse.h# #pragmapragma once once#include TShape05.h#include TShape05.h#include GlobalType05.h#include GlobalType05.hclass class TEllipseTEllipse: public : public TShapeTShape protected:protected: uintuint

84、 _ _longRlongR, _, _shortRshortR; ;public:public: TEllipse(uintTEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y, y, TColorTColor color);color); TEllipse(uintTEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y); y); TEllipseTEllipse();(); void

85、Draw(); void Draw(); void void getR(uintgetR(uint& & longRlongR, , uintuint& & shortRshortR) const;) const; void void setR(uintsetR(uint longRlongR, , uintuint shortRshortR););例例8-5 8-5 派生类的构造函数派生类的构造函数80void void TShape:getXY(uintTShape:getXY(uint& x, & x, uintuint& y) & y) constconst x = _x; x = _

86、x; y = _y; y = _y; void void TShape:setXY(uintTShape:setXY(uint x, x, uintuint y) y) _x = x; _x = x; _y = y; _y = y; TColorTColor TShape:getColorTShape:getColor() const() const return _color;return _color; void void TShape:setColor(TColorTShape:setColor(TColor color) color) _color=color; _color=colo

87、r; /TShape05.cpp/TShape05.cpp#include TShape05.h#include TShape05.h#include TColor05.h#include TColor05.h#include #include TShape:TShape(uintTShape:TShape(uint x, x, uintuint y):_colory):_color()() _x = x; _x = x; _y = y; _y = y; TShape:TShape(uintTShape:TShape(uint x, x, uintuint y,TColory,TColor c

88、olor) color) _x = x; _x = x; _y = y; _y = y;_color=color;_color=color; void void TShape:DrawTShape:Draw()() uintuint R,G,B; R,G,B;R=R=static_caststatic_cast (_(_color.getComponent(REDcolor.getComponent(RED););G=G=static_caststatic_cast (_(_color.getComponent(GREENcolor.getComponent(GREEN) ););B=B=st

89、atic_caststatic_cast (_(_color.getComponent(BLUEcolor.getComponent(BLUE); ; std:coutstd:coutDraw an shape with color(;Draw an shape with color(; std:coutstd:coutR,G,B) at point(;R,G,B) at point(; std:coutstd:cout _x, _y) _x, _y)std:endlstd:endl; ; 例例8-5 8-5 派生类的构造函数派生类的构造函数81/TEllipse05.cpp/TEllipse

90、05.cpp#include TEllipse05.h#include TEllipse05.h#include #include TEllipse:TEllipse(uintTEllipse:TEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y,TColory,TColor color):TShape(x,ycolor):TShape(x,y) _ _longRlongR = = longRlongR; ; _ _shortRshortR = = shortRshortR; ; _colo

91、r=color; _color=color; TEllipse:TEllipse(uintTEllipse:TEllipse(uint longRlongR, , uintuint shortRshortR, , uintuint x, x, uintuint y):TShape(x,yy):TShape(x,y) _ _longRlongR = = longRlongR; ; _ _shortRshortR = = shortRshortR; ; TEllipse:TEllipseTEllipse:TEllipse()() void void TEllipse:DrawTEllipse:Dr

92、aw()() uintuint x, y; x, y; getXY(xgetXY(x, y); /, y); /调用基类函数获取椭圆的圆心坐标调用基类函数获取椭圆的圆心坐标uintuint R,G,B; R,G,B;R=R=static_caststatic_cast (_(_color.getComponent(REDcolor.getComponent(RED););G=G=static_caststatic_cast (_(_color.getComponent(GREENcolor.getComponent(GREEN););B=B=static_caststatic_cast (_(

93、_color.getComponent(BLUEcolor.getComponent(BLUE);); std:coutstd:coutDraw an ellipse with color(;Draw an ellipse with color(; std:coutstd:coutR,G,B) at point(;R,G,B) at point(; std:coutstd:cout x, y) x, y)std:endlstd:endl; ; 例例8-5 8-5 派生类的构造函数派生类的构造函数82/ch8_5_main.cpp/ch8_5_main.cpp#includeTEllipse05

94、.h#includeTEllipse05.h#include#include using namespace std;using namespace std;void main()void main() TShapeTShape shp(0u,0u); shp(0u,0u);shp.setColor(TColor(0xff,0x00,0x00);shp.setColor(TColor(0xff,0x00,0x00);coutcout_FILE_:_LINE_ ;_FILE_:_LINE_ ;shp.Drawshp.Draw();();TEllipseTEllipse elps01(10u,5u

95、,0u,0u); elps01(10u,5u,0u,0u);coutcout_FILE_:_LINE_ ;_FILE_:_LINE_ ;elps01.Draw();elps01.Draw(); 例例8-5 8-5 派生类的构造函数派生类的构造函数 TEllipseTEllipse elps02(10u,5u,20u,30u,TColor(0x00,0xff,0x00);elps02(10u,5u,20u,30u,TColor(0x00,0xff,0x00);coutcout_FILE_:_LINE_ ;_FILE_:_LINE_ ;elps02.TShape:Draw();elps02.TSh

96、ape:Draw();coutcout_FILE_:_LINE_ ;_FILE_:_LINE_ ;elps02.Draw();elps02.Draw();elps02.setColor(shp.getColor();elps02.setColor(shp.getColor();coutcout_FILE_:_LINE_ ;_FILE_:_LINE_ ;elps02.Draw();elps02.Draw(); elps02.setColor(TColor(shp.getColor();elps02.setColor(TColor(shp.getColor();coutcout_FILE_:_LI

97、NE_ ;_FILE_:_LINE_ ;elps02.Draw();elps02.Draw(); 83/TShape06.h/TShape06.h# #pragmapragma once once#include GlobalType06.h#include GlobalType06.h#include TColor06.h#include TColor06.hclass class TShapeTShape private:private: uintuint _x, _y; / _x, _y; /几何形状的位置几何形状的位置protected:protected: TColorTColor

98、_color; / _color; /颜色颜色public:public:/ / TShape(uintTShape(uint x, x, uintuint y); y); TShape(uintTShape(uint x=0u, x=0u, uintuint y=0u); y=0u);/默认构默认构造函数造函数 TShape(uintTShape(uint x, x, uintuint y, y, TColorTColor color); color); TShapeTShape();(); void void getXY(uintgetXY(uint& x, & x, uintuint&

99、y) const;& y) const; void void setXY(uintsetXY(uint x, x, uintuint y); y); void Draw(); void Draw(); TColorTColor getColorgetColor() const;() const; void void setColor(TColorsetColor(TColor color); color);/TEllipse06.cpp/TEllipse06.cpp#include TEllipse06.h#include TEllipse06.h#include #include TElli

100、pse:TEllipse(uintTEllipse:TEllipse(uint longRlongR, , uintuint shortRshortR, ,/ / uintuint x, x, uintuint y, y, TColorTColor color):TShape(x,ycolor):TShape(x,y) uintuint x, x, uintuint y, y, TColorTColor color)color) _ _longRlongR = = longRlongR; ; _ _shortRshortR = = shortRshortR; ; / /在派生类构造函数中访问基

101、类保护成员在派生类构造函数中访问基类保护成员 _color=color; _color=color; TEllipse:TEllipse(uintTEllipse:TEllipse(uint longRlongR, , uintuint shortRshortR, ,/ / uintuint x, x, uintuint y):TShape(x,yy):TShape(x,y) uintuint x, x, uintuint y) y) _ _longRlongR = = longRlongR; ; _ _shortRshortR = = shortRshortR; ; 例例8-6 8-6 遗漏

102、的基类构造函数遗漏的基类构造函数84派生类的构造函数的一般总结派生类的构造函数的一般总结v派生类的构造函数的职责派生类的构造函数的职责1.1.初始化基类初始化基类2.2.初始化对象数据成员初始化对象数据成员3.3.初始化基本类型的数据成员初始化基本类型的数据成员v方式方式1.1.构造函数初始化列表构造函数初始化列表2.2.构造函数函数体构造函数函数体除非有特殊要求除非有特殊要求 ( (const const 或者或者 referencereference 数据成员只能数据成员只能由初始化列表来获得初值由初始化列表来获得初值) )v若不需做上述工作,则可不定义构造函数,而使用若不需做上述工作,则

103、可不定义构造函数,而使用系统提供的默认构造函数。系统提供的默认构造函数。 85派生类的构造函数派生类的构造函数v构造函数的调用次序构造函数的调用次序1.基类的构造函数基类的构造函数2.内嵌对象的构造函数内嵌对象的构造函数3.派生类的构造函数派生类的构造函数v因此因此基类基类 和和 内嵌对象内嵌对象 的初始化的初始化只能放在初只能放在初始化列表中始化列表中,不能放到派生类的构造函数体中,不能放到派生类的构造函数体中多继承时,基类构造函数的调用顺序: 按照定义派生类时这些基类被继承的顺序按照定义派生类时这些基类被继承的顺序, 与他们在初始化列表的次序无关。派生类的多个对象成员的构造函数的调用顺序:

104、 按照派生类定义这些成员的顺序进行按照派生类定义这些成员的顺序进行, 与他们在初始化列表中的先后次序无关。 有多个基类?有多个基类? 多个内嵌对象?多个内嵌对象?868.3.4 8.3.4 派生类的析构函数派生类的析构函数 v派生类不能继承基类的析构函数派生类不能继承基类的析构函数,需要,需要自己定义自己定义析构函数,以便在派生类对象消亡之前进行必要析构函数,以便在派生类对象消亡之前进行必要的清理工作。的清理工作。v派生类的析构函数只负责清理派生类的析构函数只负责清理它它新定义新定义的的非对象非对象数据成员,对象数据成员由对象成员所属类的析数据成员,对象数据成员由对象成员所属类的析构函数负责析

105、构。构函数负责析构。v析构函数的调用次序与构造函数相反析构函数的调用次序与构造函数相反先派生类析构函数,再基类析构函数先派生类析构函数,再基类析构函数复习:析构函数的功能在对象消亡之前进行必要的清理工作87class class TColorTColor private:private: string _color; string _color;public:public: TColor(stringTColor(string color=BLACK) color=BLACK) coutcoutTColorTColor构造函数构造函数endlendl; ; _color=color; _col

106、or=color; TColorTColor() () coutcoutTColorTColor析构函数析构函数endlendl;/Main07.cpp/Main07.cpp#include #include #include #include using namespace std;using namespace std;class class TPointTPoint protected:protected: intint _x, _y; _x, _y;public:public: TPoint(intTPoint(int x=0, x=0, intint y=0) y=0) coutco

107、utTPointTPoint构造函数构造函数(x,y)(x,y)endlendl; ; _x=x; _y=y; _x=x; _y=y; TPoint()coutTPoint()coutTPointTPoint析构函数析构函数 (_x,_y)(_x,_y)endlendl;例例8-7 8-7 派生类析构函数派生类析构函数88class class TEllipse:publicTEllipse:public TShapeTShape private:private: TPointTPoint* * pLeftFocuspLeftFocus, , RightFocusRightFocus; ;pu

108、blic:public: TEllipse():TShapeTEllipse():TShape(), (), RightFocus(2,0)RightFocus(2,0) coutcout派生类构造函数派生类构造函数endlendl; ; pLeftFocuspLeftFocus=new TPoint(1,0);=new TPoint(1,0); TEllipseTEllipse()() coutcout派生类析构派生类析构endlendl; ; if(pLeftFocusif(pLeftFocus) ) delete delete pLeftFocuspLeftFocus; ; ;intin

109、t main() main() TEllipseTEllipse elpselps; ; return 0; return 0;class class TShapeTShape protected:protected: TColorTColor* * pColorpColor; ;public:public: TShapeTShape() () coutcout基类构造函数基类构造函数endlendl; ; pColorpColor=new =new TColorTColor; ; TShapeTShape()() coutcout基类析构函数基类析构函数endlendl; ; if(0!=i

110、f(0!=pColorpColor) ) delete delete pColorpColor; ; ;例例8.7 8.7 派生类析构函数派生类析构函数89#includeusing namespace std;class baseprivate: int m_base_data;public: base(int data)m_base_data=data; coutbase object constructionendl; base()coutbase object deconstructionendl; /;8.3.4 8.3.4 派生类的析构函数派生类的析构函数90class Abcpr

111、ivate: float m_abc_data;public: Abc(float data) m_abc_data=data; cout“Object member constructionendl; Abc()coutObject member deconstructionendl; /;8.3.4 8.3.4 派生类的析构函数派生类的析构函数91class deriver:public base private:double m_deriver_data; Abc m_member1; int *m_ptr;public: deriver(int bd, float id, double

112、 dd); deriver(); void function();8.3.4 8.3.4 派生类的析构函数派生类的析构函数92deriver: deriver(int bd, float id, double dd):base(bd), m_member1(id) m_deriver_data=dd; m_ptr=new int256; if(m_ptr=NULL) coutmemory error in deriver objendl; cout“Deriver obj constructionendl;8.3.4 8.3.4 派生类的析构函数派生类的析构函数93deriver:derive

113、r() if(m_ptr!=NULL) delete m_ptr; coutDeriver obj deconstruction.endl;8.3.4 8.3.4 派生类的析构函数派生类的析构函数94void deriver:function() coutMaybe you want to do something with m_ptr in this function. endl; coutDo as you like.endl;8.3.4 8.3.4 派生类的析构函数派生类的析构函数95void main() int n(1); float x(2.0); double d(3.0); d

114、eriver obj(n,x,d); obj.function(); coutThe end of main functionendl;8.3.4 8.3.4 派生类的析构函数派生类的析构函数96v如果如果没有特殊指针没有特殊指针数据成员需要清理,可以使数据成员需要清理,可以使用由系统提供的用由系统提供的默认析构函数默认析构函数。v当派生类对象消亡时,系统当派生类对象消亡时,系统调用析构函数调用析构函数的顺的顺序与建立派生类对象时序与建立派生类对象时调用构造函数调用构造函数的顺序的顺序正正好相反好相反,即先调用,即先调用派生类的析构函数派生类的析构函数,再调用,再调用其其对象数据成员的析构函数

115、对象数据成员的析构函数,最后,最后调用基类的调用基类的析构函数。析构函数。 8.3.4 8.3.4 派生类的析构函数派生类的析构函数 97第第8 8章章 继承与派生继承与派生8.1 8.1 继承的概念继承的概念8.2 8.2 定义基类和派生类定义基类和派生类8.3 8.3 构造函数和析构函数构造函数和析构函数8.4 8.4 转换与继承转换与继承988.4 8.4 转换与继承转换与继承v深入了解派生类的成员的布局方式深入了解派生类的成员的布局方式v派生类对象与基类对象之间转换的一般规派生类对象与基类对象之间转换的一般规则则998.4.1 8.4.1 派生类到基类的转换派生类到基类的转换v派生类到

116、基类的转换有以下三种情况:派生类到基类的转换有以下三种情况:派生类对象派生类对象转换转换为基类对象;为基类对象;基类对象指针基类对象指针指向指向派生类对象;派生类对象;用派生类对象用派生类对象初始化初始化基类对象的引用。基类对象的引用。100public:public: TCircle(intTCircle(int mxmx=0, =0, intint my=0, my=0, intint mrmr=1): =1): TShape(mxTShape(mx, my) r = , my) r = mrmr; ; void Show() void Show() TShape:Show();coutT

117、Shape:Show();couttrtr=r; =r; ;intint main() main() TShapeTShape s; s; TCircleTCircle c(1,2,3); c(1,2,3); coutcoutTShapeTShape stst; s.Shows.Show(); (); coutcoutendlendl; ; coutcoutTCircleTCircle ctct; c.Showc.Show(); (); coutcoutendlendl; ; s = c;s = c;/用派生类对象为基类对象赋值用派生类对象为基类对象赋值 / s = / s = static_

118、caststatic_cast (c);(c); coutcouts=s=cttctt; s.Shows.Show(); (); coutcoutendlendl; ; return 0; return 0; /Main08.cpp/Main08.cpp#include #include using namespace std;using namespace std;class class TShapeTShape protected:protected: intint x, y; x, y;public:public: TShape(intTShape(int mxmx=0, =0, int

119、int my=0) my=0) x= x=mxmx; y=my; ; y=my; void Show() void Show() coutcoutx=xt y=y;x=xt y=y;class class TCircleTCircle : public : public TShapeTShape protected:protected: intint r; r;例例8-88-8派生类对象转换为基类对象派生类对象转换为基类对象101intint main() main() TCircleTCircle c(1,2,3); c(1,2,3); coutcoutTCircleTCircle ctct

120、; c.Showc.Show(); (); coutcoutendlendl; ; /TShapeTShape* * psps = &c; = &c; TShapeTShape* * psps = = dynamic_castdynamic_cast (&c); /*(&c); /基类对基类对象指针指向派生类对象象指针指向派生类对象 if(0!= if(0!=psps) ) coutcoutShow(); -Show(); coutcoutendlendl; ; return 0; return 0; /Main09.cpp/Main09.cpp/本文件的代码除了本文件的代码除了main()m

121、ain()函数之外,均与函数之外,均与Main08.cppMain08.cpp相同相同#include #include using namespace std;using namespace std;class class TShapeTShape protected:protected: intint x, y; x, y;public:public: TShape(intTShape(int mxmx=0, =0, intint my=0) x= my=0) x=mxmx; ; y=my; y=my; void Show() void Show() coutcoutx=xt x=xt y

122、=y;y=y;class class TCircleTCircle : public : public TShapeTShape protected:protected: intint r; r;public:public: TCircle(intTCircle(int mxmx=0, =0, intint my=0, my=0, intint mrmr=1): =1): TShape(mxTShape(mx, my) r = , my) r = mrmr; ; void Show() void Show() TShape:Show();coutTShape:Show();couttrtr=r

123、; =r; ;例例8-98-9基类对象指针指向派生类对象基类对象指针指向派生类对象102intint main() main() TCircleTCircle c(1,2,3); c(1,2,3); coutcoutTCircleTCircle ctct; c.Showc.Show(); (); coutcoutendlendl; ; TShape &ps = c;TShape &ps = c; cout&ps=ct; cout&ps=ct; ps.Show(); coutendl; ps.Show(); coutendl;return 0;return 0; /Main10.cpp/Main

124、10.cpp/本文件的代码除了本文件的代码除了main()main()函数之外,均与函数之外,均与Main08.cppMain08.cpp相同相同#include #include using namespace std;using namespace std;class class TShapeTShape protected:protected: intint x, y; x, y;public:public: TShape(intTShape(int mxmx=0, =0, intint my=0) x= my=0) x=mxmx; ; y=my; y=my; void Show() v

125、oid Show() coutcoutx=xt x=xt y=y;y=y;class class TCircleTCircle : public : public TShapeTShape protected:protected: intint r; r;public:public: TCircle(intTCircle(int mxmx=0, =0, intint my=0, my=0, intint mrmr=1): =1): TShape(mxTShape(mx, my) r = , my) r = mrmr; ; void Show() void Show() TShape:Show(

126、);coutTShape:Show();couttrtr=r; =r; ;例例8-10 8-10 用派生类对象初始化基类对象的引用用派生类对象初始化基类对象的引用103 8.4.2 8.4.2 基类到派生类的转换基类到派生类的转换vC+C+编译器可以自动将派生类对象转换为基类对象编译器可以自动将派生类对象转换为基类对象(隐式类型转换)(隐式类型转换)v从基类到派生类的自动转换是不存在的从基类到派生类的自动转换是不存在的/以下代码仅为示例以下代码仅为示例TShapeTShape s; s;TCircleTCircle c = s; c = s; /错误!不能将基类转换为派生类错误!不能将基类转换

127、为派生类TCircleTCircle* pc = &s; /* pc = &s; /错误!不能将基类转换为派生类错误!不能将基类转换为派生类TCircleTCircle& & rcrc = s; = s; /错误!不能将基类转换为派生类错误!不能将基类转换为派生类104总结总结v类类具有具有封装性、继承性和多态性封装性、继承性和多态性。v类的继承性是软件重用的一种重要机制。类的继承性是软件重用的一种重要机制。v类的继承类的继承是在现有类的基础之上,创建新类的机是在现有类的基础之上,创建新类的机制制。称现有的类为称现有的类为基类基类,新建立的类为新建立的类为派生类派生类。v派生类可以以派生类可以

128、以公有、保护和私有继承公有、保护和私有继承三种方式继三种方式继承基类;承基类;派生类继承了基类派生类继承了基类中除中除构造函数构造函数和和析构析构函数函数之外的所有成员之外的所有成员。v派生类的成员函数派生类的成员函数可以访问基类的公有成员和保可以访问基类的公有成员和保护成员;护成员;105总结总结v派生类的成员函数不能直接访问派生类的成员函数不能直接访问基类中的基类中的私有成员私有成员。v派生类继承了基类中有用的成员,发展了其自身的派生类继承了基类中有用的成员,发展了其自身的处理能力。处理能力。v派生类定义自己的构造函数和析构函数派生类定义自己的构造函数和析构函数,在定义派,在定义派生类的构造函数时,不仅要考虑派生类新增数据成生类的构造函数时,不仅要考虑派生类新增数据成员的初始化,还要注意在成员初始化列表中对基类员的初始化,还要注意在成员初始化列表中对基类构造函数的调用和内嵌对象数据成员的初始化。构造函数的调用和内嵌对象数据成员的初始化。 106

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号