




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、 第10章 承繼和派生類 目的與要求10.1 承繼與派生10.2 沖突、支配規那么和賦值兼容性10.3 虛基類10.4 靜態數據成員本章小結目的與要求 經過本章學習,應了解承繼與派生的概念,掌握派生類的定義語句格式及運用方法。知道基類成員經公有或私有派生后在派生類中的訪問權限。初步掌握沖突、支配規那么、賦值兼容性的概念。了解虛基類的概念、虛基類的語句定義格式及運用方法。了解靜態成員的定義格式、初始化方式及作用域。10.1 承繼與派生 承繼:從已有類出發建立新的類,使新類部分或全部地承繼已有類的成員。 派生:經過承繼已有的一個或多個類產生一個新類稱為派生。 10.1.1 承繼與派生的根本概念1承
2、繼與派生的定義 在定義類B時,假設運用類A的部分或全部成員,那么稱類B承繼了類A,并稱類A為基類或父類,稱類B為派生類或子類。基類與派生類或父類與子類的關系可以用圖表示。基類(父類) A派生類(子類)B承繼與派生2單一承繼 假設派生類是由一個基類派生出來的,稱為單一承繼,如派生類Score是由一個基類Student派生出的,所以為單一承繼。如下圖。 基類(父類) Student派生類(子類)Score單一承繼3多重承繼 假設派生類由多個基類派生出,稱為多重承繼。如下圖。 多重承繼基類(父類) Student基類(父類)Score派生類(子類)Information10.1.2 派生類的定義 1
3、.定義派生類的格式 class : , ; 闡明:1派生類由n個基類多重派生,當n=1時為單一承繼。2訪問權限access=public、private與protected2公有派生 假設在定義派生類時,access為public,那么定義公有派生。公有派生時,基類中一切成員在派生類中堅持各個成員的訪問權限。詳細訪問權限如下:1基類中public成員在派生類仍堅持為public成員,所以在派生類內、外都可直接運用這些成員。2基類中private成員屬于基類私有成員,所以在派生類內、外都不能直接運用這些成員。只能經過該基類公有或維護成員函數間接運用基類中的私有成員。公有派生3基類中protect
4、ed成員可在派生類中直接運用,但在派生類外不可直接訪問這類成員,必需經過派生類的公有或維護成員函數或基類的成員函數才干訪問。 【例10.1】 用學生檔案類Student派生出學生成果類Score。討論基類中公有、私有與維護數據成員在派生類中訪問權限的變化。 例程3私有派生 假設在定義派生類時,access為private那么定義了私有派生。經過私有派生后:1基類中公有成員在派生類變為私有成員,在派生類內可以運用,而在派生類外不能直接運用。2基類中維護成員在派生類變為私有成員,在派生類內可以運用,而在派生類外不能直接運用。3基類中私有成員在派生類內、外都不能直接運用,必需經過基類公有函數運用。1
5、0.1.3 派生類的構造函數與基類成員的初始化 1.派生類構造函數格式 派生類的構造函數由初始化基類數據成員構造函數與初始化派生類新增的數據成員構造函數組成。派生類構造函數的格式為: :(形參表):(實參表1),(實參表n) 派生類構造函數體 派生類構造函數格式闡明:1基類構造函數實參可以是表達式或派生類構造函數的形參。 2實參只與形參名有關,而與參數順序無關。 3冒號后基類構造函數列表稱為初始化成員列表。 派生類構造函數舉例【例10.2】多重派生實例。定義描畫圓的類Circle,定義描畫高的類High,用描畫圓的類與描畫高的類作為基類,多重派生出圓柱體類Cylinder。討論多重承繼中基類成
6、員的初始化問題。 例程2建立對象時,構造函數的調用順序 先調用基類構造函數,再調用派生類構造函數。留意: 1在派生類中并不能直接對基類的私有數據成賦初始值,必需經過公有的構造函數進展初始化任務。 2基類構造函數的調用順序取決于它們在派生類中闡明順序,而與它們在派生類構造函數中的順序無關。 3吊銷對象時,析構函數的調用順序 在吊銷派生類的對象時,析構函數的調用順序正好與構造函數的順序相反。即:先調用派生類的析構函數,再調用基類析構函數。 【例10.3】定義兩個基類Base1與Base2,并由Base1與Base2派生出派生類Derive。編寫程序,輸出派生類中構造函數與析構函數的調用關系。 例程
7、4派生類中包含對象成員的構造函數 假設派生類中包含對象成員,那么在派生類構造函數的初始化成員列表中不僅要列舉要調用的基類構造函數,而且要列舉調用的對象成員構造函數。 【例10.4】將例10.3的派生類改為包含對象成員的派生類。 例程 首先要調用基類的構造函數,再調用對象成員的構造函數,最后執行派生類的構造函數。在有多個對象成員的情況下,調用這些對象成員的構造函數的順序取決于它們在派生類中闡明順序。 10.2 沖突、支配規那么和賦值兼容性 10.2.1沖突 引例: 【例10.5】在例10.2中將描畫高的類改為描畫矩形的類Rectangle,在Rectangle類中用矩形中心坐標(x,y)、高(H
8、igh)與寬(Width)作為類的數據成員。 例程 沖突:派生類運用基類中同名成員時出現不獨一稱為沖突。處理方法:運用作用域運算符“:指明同名成員屬于哪一個基類,即: :沖突結論: 假設一個公有派生類是由兩個或多個基類派生,當基類中成員的訪問權限為public或protected且不同基類中的成員同名時,派生類運用到基類中的同名成員時出現不獨一性稱為沖突。 處理方法是運用作用域運算符指明發生沖突的成員屬于哪個基類。10.2.2 支配規那么 所謂支配規那么是指,當派生類中成員與基類中成員同名時,在不用作用域運算符時,派生類成員名優于基類成員名。 【例10.6】在【例10.5 】的派生類Cylin
9、der中,新增數據成員(x,y,z)表示圓柱體中心坐標。并從基類Rectangle中刪除(x,y)。 例程 留意:當派生的成員名與基類的成員名一樣時,在派生類中或派生類外要運用基類中的這種成員時,仍要運用作用域運算符。10.2.3 賦值兼容規那么 公有派生類的對象可賦給其基類對象,基類對象不能賦給派生類對象的規那么,稱為賦值兼容規那么。 10.2.4 基類和對象成員的幾點闡明 1任一基類在派生類中只能承繼一次。2基類成員與對象成員在運用上的差別 派生類中可直接運用基類的成員訪問權限 允許的話; 運用對象成員時,必需在對象名后加上成員運算符“.和成員名。 10.3 虛基類 10.3.1 多重派生
10、的基類拷貝 假設類B與類C由類A公有派生,而類D由類B與類C公有派生,那么類D中將包含類A的兩個拷貝(如下圖)。這種同一個基類在派生類中產生多個拷貝不僅多占用了存儲空間,而且能夠會呵斥多個拷貝數據的不一致。基類A基類A基類B基類C派生類D派生類中包含同一基類的兩個拷貝多重派生的基類拷貝【例10.7】一個公共基類在派生類中產生兩個拷貝。 例程 假設在多條承繼途徑上有一個公共的基類,那么該基類會在這些途徑中的某幾條途徑的集合處產生幾個拷貝。為使這樣的公共基類只產生一個拷貝,須將該基類闡明為虛基類。 10.3.2 虛基類 在多重派生的過程中,欲使公共的基類在派生中只有一個拷貝,可將此基類闡明成虛基類
11、。 虛基類的定義格式為: class :virtual ; 或 class : virtual ;【例10.8】定義虛基類,使派生類中只需基類的一個拷貝。例程10.4 靜態數據成員 將類的某一個數據成員的存儲類型定義為靜態類型時,那么由該類所產生的一切對象均共享為靜態成員所分配的一個存儲空間。 1靜態數據成員的定義與援用方法在類中對靜態數據成員作援用性闡明 static ;在類外文件作用域對靜態數據成員作定義性闡明 必需在類外的文件作用域中,且只能作一次定義性闡明,并分配 內存空間。 :=初值; 定義性闡明時,靜態數據成員缺省初值為0。 靜態數據成員援用格式 : 靜態數據成員 2同類不同對象的
12、靜態數據成員占用一樣的存儲空間 。3靜態數據成員置初值不受訪問權限的限制。 4為了堅持靜態數據成員取值的一致性,通常在構造函數中不給靜態數據置初值,而是在靜態數據成員的定義性闡明時指定初值。 本章小結 1.承繼 承繼:從已有類出發建立新的類,使新類部分或全部地承繼已有類的成員稱為承繼。 派生:經過承繼已有的一個或多個類產生一個新類稱為派生。 派生類的定義格式如下: class : , , 派生類體; 基類成員在派生類中訪問權限基類成員訪問權限 公有派生后的訪問權限 私有派生后的訪問權限publicpublicprivateprivate不可直接訪問不可直接訪問protectedprivatep
13、rivate 公有或私有派生后基類成員在派生類中訪問權限 派生類構造函數和析構函數 由于派生類成員由基類成員與派生類中新添加的成員組成,所以初始化任務應分為對派生類中新增成員的初始化與基類成員的初始化。由于初始化任務是由構造函數完成的,所以初始化基類成員的任務是由派生類的構造函數來完成的。 派生類構造函數的格式如下: :(形參表):(實參表1) (實參表n) ; 構造函數的調用順序是先基類后派生類,析構函數的調用順序是先派生類后基類。 2沖突、支配和賦值兼容性 沖突:派生類運用基類中同名成員時出現不獨一稱為沖突。沖突的處理方法: : 支配規那么:運用派生類中與基類中同名成員時,派生類成員優于基
14、類同名成員的規那么稱為支配規那么。 賦值的兼容性:派生類對象可賦值給基類對象,基類對象不能賦給派生類對象稱為賦值的兼容性。 3虛基類 在多重派生的過程中,欲使公共的基類在派生類中只需一個拷貝,可將此基類闡明成虛基類。虛基類的定義格式為: class :virtual ; 或 class : virtual ; 4靜態數據成員 靜態數據成員的定義必需分兩步完成,在類內作援用性闡明,在類外作定義性闡明。闡明與援用格式為: 類內作援用性闡明的格式: static ; 類外作定義性闡明的格式: :=初值; 援用格式: :例10.11# include class Student private: in
15、t No; /定義No為私有數據成員 protected: int Age; /定義Age為維護的數據成員 public: char Sex; /定義Sex為公有數據成員 Student(int no,int age,char sex) /定義類Student的構造函數 No=no;Age=age;Sex=sex; int GetNo( ) return No; /前往No的公有成員函數 int GetAge( ) return Age; /前往Age的公有成員函數 void ShowS( ) /顯示No、Age、Sex的公有成員函數 coutNo=NotAge=AgetSex=Sexendl
16、; ; 例10.12class Score : public Student /由基類Student公有派生出子類Score private: int Phi,Math; /定義類Score的私有數據成員 public: Score(int n,int a,char s,int p,int m):Student(n,a,s) /類Score的構造函數 Phi=p;Math=m; void Show( void) /顯示類Score與其父類Student的數據成員值 coutNo=GetNo( )tAge=AgetSex=Sex tPhi=PhitMath=Mathendl; ;例10.13vo
17、id main(void) Score s (101,20,M,90,80); /用類Score定義一個對象s s.ShowS( ); /類Score的對象s調用基類公有函數 ShowS() s.Show( ); /類Score的對象調用公有函數Show()coutNo=s.GetNo( )tAge=s.GetAge()tSex=s.Sexendl; 程序執行后輸出: No=101 Age=20 Sex=M No=101 Age=20 Sex=M Phi=90 Math=80 No=101 Age=20 Sex=M前往例10.21 # include class Circle /定義描畫圓的類
18、,其中(x,y)為圓心,r為半徑 protected: float x,y,r; public: Circle(float a,float b,float c) x=a;y=b;r=c;class High /定義描畫高的類 private: float h; public: High(float a) h=a; float Geth( ) return h; 例10.22class Cylinder:public Circle,private High /由圓與高派生出圓柱體類 private: float Volume; public: Cylinder(float a,float b,f
19、loat c,float d):Circle(a,b,c),High(d) /D Volume=r*r*3.1415*Geth( ); /E void Show() coutx=xty=ytr=rt h=Geth()tV= Volumeendl; ;例10.23void main (void) Cylinder cy(3,3,2,10); cy.Show(); 程序執行后輸出:x=3 y=3 r=2 h=10 V=125.664 前往例10.31# include class Base1 /定義基類Base1 private: int x; /定義基類Base1的私有數據成員x public:
20、 Base1(int a) /基類Base1的構造函數 x=a; cout調用基類1的構造函數!endl; Base1( ) /基類Base1的析構函數 cout調用基類1的析構函數!endl;例10.32class Base2 /定義基類Base2 private: int y; /定義基類Base2的私有數據成員y public: Base2(int a) /基類Base2的構造函數 y=a; cout調用基類2的構造函數!endl; Base2( ) /基類Base2的析構函數 cout調用基類2的析構函數!endl; 例10.33class Derive:public Base1,pu
21、blic Base2 /派生類Derive private: int z; /派生類Derive新增的私有數據成員 public: Derive(int a,int b):Base1(a),Base2(20) /派生類Derive構造函數 z=b; cout調用派生類構造函數!endl; Derive( ) /派生類Derive的析構函數 cout調用派生類的析構函數!endl; ;void main(void) Derive c(100,200); 例10.34程序執行后輸出: 調用基類1的構造函數! 調用基類2的構造函數! 調用派生類的構造函數! 調用派生類析構函數! 調用基類2的析構函數
22、! 調用基類1的析構函數! 前往例10.41class Derive:public Base1,public Base2 private: int z; Base1 b1,b2; /在派生類中定義基類對象成員b1,b2 public: Derive (int a,int b):Base1(a),Base2(20),b1(200),b2(a+b) /定義構造函數 z=b; cout調用派生類的構造函數!endl; Derive ( ) cout調用派生類的析構函數!endl;void main(void) Derive d(100,200); 例10.42執行程序后輸出: 調用基類1的構造函數!
23、 調用基類2的構造函數! 調用基類1的構造函數! 調用基類1的構造函數! 調用派生類的構造函數! 調用派生類的析構函數! 調用基類1的析構函數! 調用基類1的析構函數! 調用基類2的析構函數! 調用基類1的析構函數! 前往例10.51# include class Circle /定義描畫圓的基類 protected: float x,y,r;/(x,y)為圓心,r為半徑 public: Circle(float a,float b,float c) x=a;y=b;r=c; float Area( ) return (r*r*3.14159); /計算圓的面積;例10.52class Rec
24、tangle /定義描畫矩形的基類 protected: float x,y,h,w; public: Rectangle(float a, float b, float c, float d) x=a;y=b;h=c;w=d; float Area(void) /計算矩形面積 return h*w; ;例10.53class Cylinder:public Circle,public Rectangle /描畫一個圓柱體的派生類 private: float Volume; /圓柱體的體積 public: Cylinder(float a,float b,float c):Circle(a,
25、b,c),Rectangle(10,10,c,c) /A Volume=Area( )*h; /B float GetV( )return Volume; void Show(void) coutx=xty=yendl;/C;例10.54 void main (void) Cylinder cy(3,3,2); cy.Show();coutVolume=cy.GetV()endl;程序執行后輸出: x=3 y=3 Volume=25.1327 前往例10.55# include class Circle /定義描畫圓的基類 protected: float x,y,r;/(x,y)為圓心,r為
26、半徑 public: Circle(float a,float b,float c) x=a;y=b;r=c; float Area( ) return (r*r*3.14159); /計算圓的面積;例10.56class Rectangle /定義描畫矩形的基類 protected: float x,y,h,w; public: Rectangle(float a, float b, float c, float d) x=a;y=b;h=c;w=d; float Area(void) /計算矩形面積 return h*w; ;例10.57class Cylinder:public Circ
27、le,public Rectangle/描畫一個圓柱體的派生類 private: float Volume; /圓柱體的體積 public: Cylinder(float a,float b,float c):Circle(a,b,c),Rectangle(10,10,c,c) /D Volume=Circle:Area( )*h; /E float GetV( )return Volume; void Show(void) coutx=Circle:xty=Circle:yendl;/F;例10.58 void main (void) Cylinder cy(3,3,2); cy.Show(
28、);coutVolume=cy.GetV()endl;程序執行后輸出: x=3 y=3 Volume=25.1327 前往例10.61# include class Circle /定義描畫圓的基類,其中(x,y)為圓心,r為半徑 protected: float x,y,r; public:Circle(float a,float b,float c) x=a;y=b;r=c;float Area( ) return (r*r*3.14159); /計算圓的面積;class Rectangle /定義描畫矩形的基類 protected: float h,w; public: 例10.62 R
29、ectangle(float c, float d) h=c;w=d; float Area(void) /計算矩形面積 return h*w;class Cylinder:public Circle,public Rectangle /描畫一個圓柱體的派生類 private: float x,y,z,Volume; /圓柱體的中心坐標與體積 public: Cylinder(float a,float b,float c,float d):Circle(a,b,d),Rectangle(d,d) x=a;y=b;z=c; Volume=Circle:Area( )*h; 例10.63 float GetV( ) return Volume; void Show(void) coutx=xty=y tz=z endl;void main (void) Cylinder cy(3,3,3,2); cy.Show();coutVolume=cy.GetV()endl;程序執行后輸出:x=3 y=3 z=3Volume=25.1327 前往例10.71# include cla
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工作中如何提高專注力和時間利用率
- 工業自動化技術的前沿進展
- 工業自動化技術的發展及市場應用
- 工作中的決策能力與執行力培養
- 工業設備能效優化策略
- 工業領域安全防護系統設計
- 工作繁忙人士的健康膳食建議
- 工作流程優化及資源管理方法
- 工廠設備選型與采購策略培訓
- 工程測量中的遙感技術應用分析
- 食品供應不合格產品退換方案
- 華為大學人才培養與發展實踐
- 年產12000噸水合肼(100%)項目環評報告書
- 《有機波譜分析》期末考試試卷及參考答案
- 最詳細的整車開發流程
- 部編版七年級歷史(下)材料論述題專項訓練
- 年產1000噸乳酸的生產工藝設計
- 博克服裝CAD制版說明操作手冊(共95頁)
- 光電效應測普朗克常數-實驗報告
- (完整word版)數據模型與決策課程案例分析
- 物業服務參與校園文化建設及舉辦大型活動配合措施
評論
0/150
提交評論