C++高級語言程序設(shè)計(jì)第八章_第1頁
C++高級語言程序設(shè)計(jì)第八章_第2頁
C++高級語言程序設(shè)計(jì)第八章_第3頁
C++高級語言程序設(shè)計(jì)第八章_第4頁
C++高級語言程序設(shè)計(jì)第八章_第5頁
已閱讀5頁,還剩59頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院1C+高級語言程序設(shè)計(jì)第8章 繼承與派生北京郵電大學(xué)信息與通信工程學(xué)院第8章 繼承與派生8.1 繼承的概念8.2 定義基類和派生類8.3 構(gòu)造函數(shù)和析構(gòu)函數(shù)8.4 轉(zhuǎn)換與繼承回顧上章:類對象本章:繼承的概念和分類;繼承的用法:如何繼承某個祖先類的功能,如何為后代類添加新的功能。2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-4-8.1 繼承的概念自行車8.1 繼承的概念-例子自行車 Bicycle8.1 繼承的概念-例子雙人自行車 Tandem Bike8.1 繼承的概念-例子競速自行車 Racing Bike8.1 繼承的概念-例子山地車 M

2、ountain Bike8.1 繼承的概念-例子山地車?yán)^承了自行車的特征山地車 “派生”于 自行車。8.1 繼承的概念類的繼承是在現(xiàn)有類的基礎(chǔ)之上,創(chuàng)建新類的機(jī)制。稱現(xiàn)有的類為基類,新建立的類為派生類。Bike基類Tandem Bike派生類派生于int Wheel;bool Run();int Wheel;bool Run();int Seat;父類子類 從基類繼承2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-11-8.2 定義基類和派生類8.2 定義基類和派生類定義派生類時(shí)要聲明繼承方式 訪問控制受繼承方式的 影響繼承導(dǎo)致一種特殊的語法現(xiàn)象:同名覆蓋。三種繼承方式 public、pro

3、tected、private 不同繼承方式的影響主要體現(xiàn)在: 派生類 成員 對基類成員的訪問控制。 派生類 對象 對基類成員的訪問控制、2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-13-8.2.1 簡單的繼承和派生例8-1 簡單的繼承和派生問題:想在屏幕上畫出正三角形、矩形或圓形方法一:結(jié)構(gòu)化方法DrawTri (int x, int y, char color, int side);DrawRect (int x, int y, char color, int length, int width)DrawCircle(int x, int y, char color, int Radi

4、us)方法二:面向?qū)ο螅縞lass circle 圓形class rectangle 矩形class triangle 三角形基類: class shape色彩 color位置 (x, y)shapecirclerectangletriangle泛化?class TShapeprivate: uint _x, _y; /幾何形狀的位置public: TShape(); uint getX(); uint getY(); void setX(uint x); void setY(uint y); void Draw();成員函數(shù)的分類構(gòu)造函數(shù)設(shè)置屬性值讀取屬性值/TShape01.cpp: 類T

5、Shape的實(shí)現(xiàn)#include TShape01.h#include using namespace std; TShape:TShape() _x = 10; _y = 10;void TShape:Draw() coutThis is TShape:Draw()endl;成員函數(shù)的分類構(gòu)造函數(shù)設(shè)置屬性值讀取屬性值執(zhí)行#include TShape01.hclass TEllipse: public TShape public: void Draw();成員函數(shù)的分類構(gòu)造函數(shù)設(shè)置屬性值讀取屬性值執(zhí)行/ TEllipse01.cpp: 類TEllipse的實(shí)現(xiàn)#include TEllips

6、e01.h#include using namespace std; void TEllipse:Draw() coutDraw an ellipse with colorendl;成員函數(shù)的分類構(gòu)造函數(shù)設(shè)置屬性值讀取屬性值2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-19-8.2.2 定義派生類8.2.2 定義派生類class 派生類名 : 繼承方式 基類1, 繼承方式 基類2, , 繼承方式 基類n 派生類成員聲明; ;例如: 已有基類b1和b2,定義派生類derive,其中包括私有整型成員 newInt,公有函數(shù)成員 int newFun(),私有函數(shù)成員 int max(int a

7、, int b);寫出類derive的定義class derive : public b1 , private b2private: int newInt;public: void newFun();private:int max( int a, int b );2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-21-8.2.3 訪問控制和繼承關(guān)系8.2.3 訪問控制和繼承關(guān)系類成員的可見性公共成員:public保護(hù)成員:protected私有成員:private繼承的方式公有繼承(public)保護(hù)繼承(protected)私有繼承(private)派生類繼承了基類中的所有成員,但不包括構(gòu)造

8、函數(shù)析構(gòu)函數(shù)8.2.3 訪問控制和繼承關(guān)系不同繼承方式?jīng)Q定的不同訪問控制權(quán)限體現(xiàn)在:派生類的成員函數(shù)對其繼承的基類成員的訪問控制;其它模塊通過派生類對象對其繼承的基類成員的訪問控制。private:protected:public:基類?派生類publicprotectedprivate繼承方式?jīng)Q定繼承成員的訪問權(quán)限繼承來的成員的訪問權(quán)限?1. 公有繼承 公有繼承的派生類定義形式: class 派生類名:public 基類名派生類新成員定義;;private:protected:public:基類?派生類基類成員 在派生類中的訪問屬性不變。派生類的成員函數(shù) 可以訪問基類的公有成員和保護(hù)成員,不

9、能訪問基類的私有成員;派生類以外的其它函數(shù) 可以通過派生類的對象,訪問從基類繼承的公有成員, 但不能訪問從基類繼承的保護(hù)成員和私有成員。privateprotectedpublic派生類成員函數(shù)可以訪問派生類對象基類成員的屬性publicclass 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

10、X,Y;class Rectangle: public Point /派生類public:/新增公有函數(shù)成員void InitR(float x, float y, float w, float h) InitP(x,y); /訪問基類公有函數(shù) W=w;H=h;float GetH() return H;float GetW() return W;private:/新增私有數(shù)據(jù)成員float W,H;int main() Rectangle rect; coutrect.X; /可否? coutrect.GetX(); /可否? return 0;此語句可否改為:X=x; Y=y;派生類中的

11、成員函數(shù) 可以直接訪問基類中的public和protected成員,但不能訪問基類的private成員。class 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;class Rect: public Point public:/新增公有函數(shù)成員Rect(float x, float y, fl

12、oat w, float h) X=x; Y=y; W=w;H=h;float GetH() return H;float GetW() return W;private:/新增私有數(shù)據(jù)成員float W,H;int main() Rect r(1, 2, 3, 4); coutr.X; coutr.GetX(); return 0A. public:B. private:C. protected:D. 嘛也不填 ?此處填啥,才能讓編譯器只對第3行代碼報(bào)錯?2. 私有繼承 私有繼承的派生類定義形式: class 派生類名:private 基類名派生類新成員定義;;private:protect

13、ed:public:基類?派生類基類成員 在派生類中的訪問屬性都變成 private。派生類的成員函數(shù) 可以訪問基類的公有成員和保護(hù)成員,不能訪問基類的私有成員;派生類以外的其它函數(shù) 不能通過派生類的對象,訪問從基類繼承的任何成員。privateprivateprivate派生類成員函數(shù)可以訪問基類成員的屬性private派生類對象3. 保護(hù)繼承 私有繼承的派生類定義形式: class 派生類名:protected 基類名派生類新成員定義;;private:protected:public:基類?派生類基類成員 公有成員和保護(hù)成員在派生類中變成保護(hù)類型的,基類的私有成員屬性不變。派生類的成員函

14、數(shù) 可以訪問基類的公有成員和保護(hù)成員,不能訪問基類的私有成員;派生類以外的其它函數(shù) 不能通過派生類的對象,訪問從基類繼承的任何成員。privateprotectedprotected派生類成員函數(shù)可以訪問基類成員的屬性prot-ected派生類對象私有繼承和保護(hù)繼承的區(qū)別private:protected:public:父類privateprotectedprotected子類protectedprivate:protected:public:父類privateprivateprivate:子類privateprivateprivateprivate:孫類privateprotectedpub

15、lic孫類成員函數(shù)無法訪問protectedpublicprivateprotectedprotected孫類孫類成員函數(shù)可以訪問繼承方式影響訪問控制public:protected:private:publicpublicprotectedprivateprotectedprotectedprotectedprivateprivateprivateprivateprivate基類存取方式繼承類型派生類繼承的基類成員的訪問屬性2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-31-8.2.4 同名覆蓋8.2.4 同名覆蓋 override class base public: void f (

16、) coutbaseendl; ;class deriver: public base public: void f () coutderiverendl; ;int main( ) deriver derobj; derobj.f (); return 0;輸出結(jié)果?A: baseB: deriver在派生類中聲明了一個與基類成員同名的新成員OverRide只能訪問到派生類中的同名新成員在派生類作用域內(nèi)或者在類外通過派生類的對象直接使用這個成員名class Shape public: void Draw();protected: ;class Triangle: public Shape p

17、ublic: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;圖形類中的同名覆蓋2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-34-8.3 構(gòu)造函數(shù)和析構(gòu)函數(shù)8.3 構(gòu)造函數(shù)與析構(gòu)函數(shù) 基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被派生類所繼承派生類一般需要定義自己的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造及析構(gòu)函數(shù)通常

18、會受到基類構(gòu)造及析構(gòu)函數(shù)的影響2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-36-8.3.1 基類只有無參數(shù)構(gòu)造函數(shù)8.3.1 基類只有無參數(shù)的構(gòu)造函數(shù)在基類具有無參構(gòu)造函數(shù),派生類又沒有定義構(gòu)造函數(shù)的時(shí)候,系統(tǒng)會自動的調(diào)用基類無參構(gòu)造函數(shù),來構(gòu)造派生類對象中的基類成分。如果基類沒有無參構(gòu)造函數(shù),派生類也不定義自己的構(gòu)造函數(shù),在編譯的時(shí)候,一定會有語法錯誤。2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-38-8.3.2 派生類的構(gòu)造函數(shù)8.3.2 派生類的構(gòu)造函數(shù)不參與繼承的特殊函數(shù)構(gòu)造函數(shù)析構(gòu)函數(shù)作為特權(quán)地位的友元函數(shù)賦值運(yùn)算符函數(shù)派生類需要自己定義的構(gòu)造函數(shù)和析構(gòu)函數(shù)。8.3.2

19、派生類的構(gòu)造函數(shù)派生類名:派生類名 (基類所需形參,本類成員所需形參) :基類1(基類參數(shù)表1), ,基類n(基類參數(shù)表n),對象成員1(對象參數(shù)表1), ,對象成員m(對象參數(shù)表m) 本類基本類型數(shù)據(jù)成員初始化; 初始化列表/TShape04.cpp#include TShape04.h#include TShape:TShape(uint x, uint y) _x = x; _y = y;void TShape:Draw() std:coutThis is TShape:Draw()std:endl;void TShape:getXY(uint& x, uint& y) x = _x;

20、y = _y;void TShape:getRGB(uchar& R, uchar& G, uchar& B) R = _RED; G = _GREEN; B = _BLUE;/TShape04.htypedef unsigned int uint;typedef unsigned char uchar;class TShapeprivate: uint _x, _y; /幾何形狀的位置protected: /*聲明幾何形狀的顏色。允許TShape的派生類直接訪問這些顏色屬性, *而不允許在類外通過類的對象直接訪問這些屬性 */ uchar _RED, _GREEN, _BLUE;public

21、: TShape(uint x, uint y); void getXY(uint& x, uint& y); void setXY(uint x, uint y); void Draw(); void getRGB(uchar& R, uchar& G, uchar& B); void setRGB(uchar R, uchar G, uchar B);例8-4 單繼承派生類構(gòu)造函數(shù)/TEllipse04.cpp#include TEllipse04.h#include TEllipse:TEllipse(uint longR, uint shortR, uint x, uint y):TS

22、hape(x,y) _longR = longR; _shortR = shortR; /在派生類構(gòu)造函數(shù)中初始化基類保護(hù)成員 _RED = 0 x00; _GREEN = 0 x00; _BLUE = 0 x00; TEllipse:TEllipse()void TEllipse:Draw() uint x, y; getXY(x, y); /調(diào)用基類函數(shù)獲取橢圓的圓心坐標(biāo) std:coutDraw an ellipse with color(; std:coutstatic_cast(_RED) , static_cast(_GREEN), static_cast(_BLUE) ) at

23、point(;/ std:cout_x,_y)std:endl; /錯誤!在派生類中不能 /訪問基類私有成員 std:cout x, y)std:endl;/TEllipse04.h#include TShape04.hclass TEllipse: public TShape protected: uint _longR, _shortR;public: TEllipse(uint longR, uint shortR, uint x, uint y); TEllipse(); void Draw(); void getR(uint& longR, uint& shortR); void s

24、etR(uint longR, uint shortR);例8-4 單繼承派生類構(gòu)造函數(shù)例8-4 單繼承派生類構(gòu)造函數(shù)2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-44-8.3.3 包含內(nèi)嵌對象的派生類構(gòu)造函數(shù)派生類名:派生類名 (基類所需形參,本類成員所需形參) :基類1(基類參數(shù)表1), ,基類n(基類參數(shù)表n),對象成員1(對象參數(shù)表1), ,對象成員m(對象參數(shù)表m) 本類基本類型數(shù)據(jù)成員初始化; 初始化列表/TShape05.h#pragma once#include GlobalType05.h#include TColor05.hclass TShapeprivate: ui

25、nt _x, _y; /幾何形狀的位置protected: TColor _color; /顏色public: TShape(uint x, uint y); TShape(uint x, uint y, TColor color); TShape(); void getXY(uint& x, uint& y) const; void setXY(uint x, uint y); void Draw(); TColor getColor() const; void setColor(TColor color);/ GlobalType05.h#pragma once /預(yù)處理指令,避免重復(fù)包含

26、本頭文件typedef unsigned int uint;typedef unsigned char uchar;/TColor05.h#pragma once#include GlobalType05.henum EColorComponent RED, GREEN, BLUE;class TColorprivate: uchar _RED, _GREEN, _BLUE;public: TColor(const uchar R=0 x00, const uchar G=0 x00, const uchar B=0 x00);/普通構(gòu)造函數(shù) TColor(const TColor& colo

27、r);/拷貝構(gòu)造函數(shù) TColor& operator =(const TColor& color);/重載賦值運(yùn)算符 void setColor(uchar R, uchar G, uchar B); uchar getComponent(EColorComponent component) const;例8-5 派生類的構(gòu)造函數(shù)/TColor05.cpp#include TColor05.hTColor:TColor(uchar R/* =0 x00 */, /普通構(gòu)造函數(shù) uchar G/* =0 x00 */, uchar B/* =0 x00 */) _RED = R; _GREEN

28、 = G; _BLUE = B;TColor:TColor(const TColor& color)/拷貝構(gòu)造函數(shù) _RED = color._RED; _GREEN = color._GREEN; _BLUE = color._BLUE;void TColor:setColor(uchar R, uchar G, uchar B) _RED = R; _GREEN = G; _BLUE = B;/TEllipse.h#pragma once#include TShape05.h#include GlobalType05.hclass TEllipse: public TShape prote

29、cted: uint _longR, _shortR;public: TEllipse(uint longR, uint shortR, uint x, uint y, TColor color); TEllipse(uint longR, uint shortR, uint x, uint y); TEllipse(); void Draw(); void getR(uint& longR, uint& shortR) const; void setR(uint longR, uint shortR);例8-5 派生類的構(gòu)造函數(shù)例8-5 派生類的構(gòu)造函數(shù)/TShape06.h#pragma

30、once#include GlobalType06.h#include TColor06.hclass TShapeprivate: uint _x, _y; /幾何形狀的位置protected: TColor _color; /顏色public:/ TShape(uint x, uint y); TShape(uint x=0u, uint y=0u);/默認(rèn)構(gòu)造函數(shù) TShape(uint x, uint y, TColor color); TShape(); void getXY(uint& x, uint& y) const; void setXY(uint x, uint y); v

31、oid Draw(); TColor getColor() const; void setColor(TColor color);/TEllipse06.cpp#include TEllipse06.h#include TEllipse:TEllipse(uint longR, uint shortR,/ uint x, uint y, TColor color):TShape(x,y) uint x, uint y, TColor color) _longR = longR; _shortR = shortR; /在派生類構(gòu)造函數(shù)中訪問基類保護(hù)成員 _color=color;TEllipse

32、:TEllipse(uint longR, uint shortR,/ uint x, uint y):TShape(x,y) uint x, uint y) _longR = longR; _shortR = shortR;例8-6 遺漏的基類構(gòu)造函數(shù)派生類的構(gòu)造函數(shù)的一般總結(jié)派生類的構(gòu)造函數(shù)的職責(zé)初始化基類初始化對象數(shù)據(jù)成員初始化基本類型的數(shù)據(jù)成員方式構(gòu)造函數(shù)初始化列表構(gòu)造函數(shù)函數(shù)體除非有特殊要求 (const 或者 reference 數(shù)據(jù)成員只能由初始化列表來獲得初值)若不需做上述工作,則可不定義構(gòu)造函數(shù),而使用系統(tǒng)提供的默認(rèn)構(gòu)造函數(shù)。 派生類的構(gòu)造函數(shù)構(gòu)造函數(shù)的調(diào)用次序基類的構(gòu)造函數(shù)

33、內(nèi)嵌對象的構(gòu)造函數(shù)派生類的構(gòu)造函數(shù)因此基類 和 內(nèi)嵌對象 的初始化只能放在初始化列表中,不能放到派生類的構(gòu)造函數(shù)體中多繼承時(shí),基類構(gòu)造函數(shù)的調(diào)用順序: 按照定義派生類時(shí)這些基類被繼承的順序 與他們在初始化列表的次序無關(guān)。派生類的多個對象成員的構(gòu)造函數(shù)的調(diào)用順序 按照派生類定義這些成員的順序進(jìn)行 與他們在初始化列表中的先后次序無關(guān)。 有多個基類? 多個內(nèi)嵌對象?2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-52-8.3.4 析構(gòu)函數(shù)8.3.4 析構(gòu)函數(shù) 派生類不能繼承基類的析構(gòu)函數(shù),需要自己定義析構(gòu)函數(shù)。派生類的析構(gòu)函數(shù)一般只負(fù)責(zé)清理位于堆區(qū)的成員,而不需清理位于棧區(qū)的成員。析構(gòu)函數(shù)的調(diào)用次

34、序與構(gòu)造函數(shù)相反先派生類析構(gòu)函數(shù),再基類析構(gòu)函數(shù) 復(fù)習(xí):析構(gòu)函數(shù)的功能在對象消亡之前進(jìn)行必要的清理工作class TColorprivate: string _color;public: TColor(string color=BLACK) coutTColor構(gòu)造函數(shù)endl; _color=color; TColor() coutTColor析構(gòu)函數(shù)endl;/Main07.cpp#include #include using namespace std;class TPointprotected: int _x, _y;public: TPoint(int x=0, int y=0) c

35、outTPoint構(gòu)造函數(shù)(x,y)endl; _x=x; _y=y; TPoint()coutTPoint析構(gòu)函數(shù) (_x,_y)endl;例8-7 派生類析構(gòu)函數(shù)class TEllipse:public TShape private: TPoint* pLeftFocus, RightFocus;public: TEllipse():TShape(), RightFocus(2,0) cout派生類構(gòu)造函數(shù)endl; pLeftFocus=new TPoint(1,0); TEllipse() cout派生類析構(gòu)endl; if(pLeftFocus) delete pLeftFocus

36、; ;int main() TEllipse elps; return 0;class TShapeprotected: TColor* pColor;public: TShape() cout基類構(gòu)造函數(shù)endl; pColor=new TColor; TShape() cout基類析構(gòu)函數(shù)endl; if(0!=pColor) delete pColor; ;例8.7 派生類析構(gòu)函數(shù)2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-56-8.4 轉(zhuǎn)換與繼承8.4 轉(zhuǎn)換與繼承深入了解派生類的成員的布局方式派生類對象與基類對象之間轉(zhuǎn)換的一般規(guī)則2022/8/12北京郵電大學(xué)信息與通信工程學(xué)院-58-8.4.1 派生類到基類的轉(zhuǎn)換8.4 轉(zhuǎn)換與繼承派生類到基類的轉(zhuǎn)換有以下三種情況:派生類對象轉(zhuǎn)換為基類對象;基類對象指針指向派生類對象;用派生類對象初始化基類對象的引用。public: TCircle(int mx=0, int my=0, int mr=1): TShape(mx, my) r = mr; void Show() TShape:Show();couttr=r; ;int main() TShape s; TCircle c(1,2,3); coutTShape st; s.Show();

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論