




已閱讀5頁,還剩63頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1 第七章繼承與派生 清華大學(xué)鄭莉 C 語言程序設(shè)計 2 本章主要內(nèi)容 類的繼承類成員的訪問控制單繼承與多繼承派生類的構(gòu)造 析構(gòu)函數(shù)類成員的標識與訪問 3 類的繼承與派生 保持已有類的特性而構(gòu)造新類的過程稱為繼承 在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過程稱為派生 被繼承的已有類稱為基類 或父類 派生出的新類稱為派生類 4 繼承與派生問題舉例 類的繼承與派生 5 繼承與派生問題舉例 類的繼承與派生 貓科 6 繼承與派生問題舉例 類的繼承與派生 7 繼承與派生問題舉例 類的繼承與派生 8 繼承與派生的目的 繼承的目的 實現(xiàn)代碼重用 派生的目的 當(dāng)新的問題出現(xiàn) 原有程序無法解決 或不能完全解決 時 需要對原有程序進行改造 類的繼承與派生 9 派生類的聲明 class派生類名 繼承方式基類名 成員聲明 類的繼承與派生 10 繼承方式 不同繼承方式的影響主要體現(xiàn)在 派生類成員對基類成員的訪問權(quán)限通過派生類對象對基類成員的訪問權(quán)限三種繼承方式公有繼承私有繼承保護繼承 類成員的訪問控制 11 公有繼承 public 基類的public和protected成員的訪問屬性在派生類中保持不變 但基類的private成員不可直接訪問 派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員 但不能直接訪問基類的private成員 通過派生類的對象只能訪問基類的public成員 類成員的訪問控制 12 例7 1公有繼承舉例 classPoint 基類Point類的聲明 public 公有函數(shù)成員voidInitP floatxx 0 floatyy 0 X xx Y yy voidMove floatxOff floatyOff X xOff Y yOff floatGetX returnX floatGetY returnY private 私有數(shù)據(jù)成員floatX Y 類成員的訪問控制 classRectangle publicPoint 派生類聲明 public 新增公有函數(shù)成員voidInitR floatx floaty floatw floath InitP x y W w H h 調(diào)用基類公有成員函數(shù)floatGetH returnH floatGetW returnW private 新增私有數(shù)據(jù)成員floatW H 13 include includeusingnamecpacestd intmain Rectanglerect rect InitR 2 3 20 10 通過派生類對象訪問基類公有成員rect Move 3 2 cout rect GetX rect GetY rect GetH rect GetW endl return0 14 15 16 私有繼承 private 基類的public和protected成員都以private身份出現(xiàn)在派生類中 但基類的private成員不可直接訪問 派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員 但不能直接訪問基類的private成員 通過派生類的對象不能直接訪問基類中的任何成員 類成員的訪問控制 17 例7 2私有繼承舉例 classRectangle privatePoint 派生類聲明 public 新增外部接口voidInitR floatx floaty floatw floath InitP x y W w H h 訪問基類公有成員voidMove floatxOff floatyOff Point Move xOff yOff floatGetX returnPoint GetX floatGetY returnPoint GetY floatGetH returnH floatGetW returnW private 新增私有數(shù)據(jù)floatW H 類成員的訪問控制 include includeusingnamecpacestd intmain 通過派生類對象只能訪問本類成員Rectanglerect rect InitR 2 3 20 10 rect Move 3 2 cout rect GetX rect GetY rect GetH rect GetW endl return0 18 19 保護繼承 protected 基類的public和protected成員都以protected身份出現(xiàn)在派生類中 但基類的private成員不可直接訪問 派生類中的成員函數(shù)可以直接訪問基類中的public和protected成員 但不能直接訪問基類的private成員 通過派生類的對象不能直接訪問基類中的任何成員 類成員的訪問控制 20 protected成員的特點與作用 對建立其所在類對象的模塊來說 它與private成員的性質(zhì)相同 對于其派生類來說 它與public成員的性質(zhì)相同 既實現(xiàn)了數(shù)據(jù)隱藏 又方便繼承 實現(xiàn)代碼重用 類成員的訪問控制 21 例7 3protected成員舉例 classA protected intx intmain Aa a x 5 錯誤 類成員的訪問控制 classA protected intx classB publicA public voidFunction voidB Function x 5 正確 22 23 類型兼容規(guī)則 一個公有派生類的對象在使用上可以被當(dāng)作基類的對象 反之則禁止 具體表現(xiàn)在 派生類的對象可以被賦值給基類對象 派生類的對象可以初始化基類的引用 指向基類的指針也可以指向派生類 通過基類對象名 指針只能使用從基類繼承的成員 類型兼容 24 例7 4類型兼容規(guī)則舉例 通用顯示程序的幻想 includeusingnamecpacestd classB0 基類B0聲明 public voiddisplay cout B0 display endl 公有成員函數(shù) 類型兼容 classB1 publicB0 public voiddisplay coutdisplay 對象指針 成員名 25 intmain 主函數(shù) B0b0 聲明B0類對象B1b1 聲明B1類對象D1d1 聲明D1類對象B0 p 聲明B0類指針p 運行結(jié)果 B0 display B0 display B0 display 26 27 基類與派生類的對應(yīng)關(guān)系 單繼承派生類只從一個基類派生 多繼承派生類從多個基類派生 多重派生由一個基類派生出多個不同的派生類 多層派生派生類又作為基類 繼續(xù)派生新的類 單繼承與多繼承 28 多繼承時派生類的聲明 class派生類名 繼承方式1基類名1 繼承方式2基類名2 成員聲明 注意 每一個 繼承方式 只用于限制對緊隨其后之基類的繼承 單繼承與多繼承 29 多繼承舉例 classA public voidsetA int voidshowA private inta classB public voidsetB int voidshowB private intb classC publicA privateB public voidsetC int int int voidshowC private intc 單繼承與多繼承 voidA setA intx a x voidB setB intx b x voidC setC intx inty intz 派生類成員直接訪問基類的 公有成員setA x setB y c z 其他函數(shù)實現(xiàn)略 intmain Cobj obj setA 5 obj showA obj setC 6 7 9 obj showC obj setB 6 錯誤 obj showB 錯誤return0 30 31 繼承時的構(gòu)造函數(shù) 派生類中需要聲明自己的構(gòu)造函數(shù) 聲明構(gòu)造函數(shù)時 只需要對本類中新增成員進行初始化 對繼承來的基類成員的初始化 自動調(diào)用基類構(gòu)造函數(shù)完成 派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)傳遞參數(shù) 派生類的構(gòu)造 析構(gòu)函數(shù) 32 單一繼承時的構(gòu)造函數(shù) 派生類名 派生類名 基類所需的形參 本類成員所需的形參 基類名 參數(shù)表 本類成員初始化賦值語句 派生類的構(gòu)造 析構(gòu)函數(shù) 33 單一繼承時的構(gòu)造函數(shù)舉例 includeusingnamespacestd classB public B B inti B voidPrint const private intb 派生類的構(gòu)造 析構(gòu)函數(shù) B B b 0 cout B sdefaultconstructorcalled endl B B inti b i cout B sconstructorcalled endl B B cout B sdestructorcalled endl voidB Print const cout b endl 34 classC publicB public C C inti intj C voidPrint const private intc 35 C C c 0 cout C sdefaultconstructorcalled endl C C inti intj B i c j cout C sconstructorcalled endl C C cout C sdestructorcalled endl voidC Print const B Print cout c endl intmain Cobj 5 6 obj Print 36 37 派生類與基類的構(gòu)造函數(shù) 當(dāng)基類中聲明有默認形式的構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時 派生類構(gòu)造函數(shù)可以不向基類構(gòu)造函數(shù)傳遞參數(shù) 若基類中未聲明構(gòu)造函數(shù) 派生類中也可以不聲明 全采用默認形式構(gòu)造函數(shù) 當(dāng)基類聲明有帶形參的構(gòu)造函數(shù)時 派生類也應(yīng)聲明帶形參的構(gòu)造函數(shù) 并將參數(shù)傳遞給基類構(gòu)造函數(shù) 程序舉例constrc base cpp 派生類的構(gòu)造 析構(gòu)函數(shù) 38 多繼承時的構(gòu)造函數(shù) 派生類名 派生類名 基類1形參 基類2形參 基類n形參 本類形參 基類名1 參數(shù) 基類名2 參數(shù) 基類名n 參數(shù) 本類成員初始化賦值語句 派生類的構(gòu)造 析構(gòu)函數(shù) 39 多繼承且有內(nèi)嵌對象時的構(gòu)造函數(shù) 派生類名 派生類名 基類1形參 基類2形參 基類n形參 本類形參 基類名1 參數(shù) 基類名2 參數(shù) 基類名n 參數(shù) 對象數(shù)據(jù)成員的初始化 本類成員初始化賦值語句 派生類的構(gòu)造 析構(gòu)函數(shù) 40 構(gòu)造函數(shù)的調(diào)用順序 1 調(diào)用基類構(gòu)造函數(shù) 調(diào)用順序按照它們被繼承時聲明的順序 從左向右 2 調(diào)用成員對象的構(gòu)造函數(shù) 調(diào)用順序按照它們在類中聲明的順序 3 派生類的構(gòu)造函數(shù)體中的內(nèi)容 派生類的構(gòu)造 析構(gòu)函數(shù) 41 例7 5派生類構(gòu)造函數(shù)舉例 includeusingnamecpacestd classB1 基類B1 構(gòu)造函數(shù)有參數(shù) public B1 inti cout constructingB1 i endl classB2 基類B2 構(gòu)造函數(shù)有參數(shù) public B2 intj cout constructingB2 j endl classB3 基類B3 構(gòu)造函數(shù)無參數(shù) public B3 cout constructingB3 endl 派生類的構(gòu)造 析構(gòu)函數(shù) classC publicB2 publicB1 publicB3 public 派生類的公有成員C inta intb intc intd B1 a memberB2 d memberB1 c B2 b private 派生類的私有對象成員B1memberB1 B2memberB2 B3memberB3 intmain Cobj 1 2 3 4 運行結(jié)果 constructingB22constructingB11constructingB3 constructingB13constructingB24constructingB3 42 43 拷貝構(gòu)造函數(shù) 若建立派生類對象時調(diào)用默認拷貝構(gòu)造函數(shù) 則編譯器將自動調(diào)用基類的默認拷貝構(gòu)造函數(shù) 若編寫派生類的拷貝構(gòu)造函數(shù) 則需要為基類相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù) 例如 C C C c1 B c1 派生類的構(gòu)造 析構(gòu)函數(shù) 44 繼承時的析構(gòu)函數(shù) 析構(gòu)函數(shù)也不被繼承 派生類自行聲明聲明方法與一般 無繼承關(guān)系時 類的析構(gòu)函數(shù)相同 不需要顯式地調(diào)用基類的析構(gòu)函數(shù) 系統(tǒng)會自動隱式調(diào)用 析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反 派生類的構(gòu)造 析構(gòu)函數(shù) 45 例7 6派生類析構(gòu)函數(shù)舉例 派生類的構(gòu)造 析構(gòu)函數(shù) includeusingnamecpacestd classB1 基類B1聲明 public B1 inti cout constructingB1 i endl B1 cout destructingB1 endl classB2 基類B2聲明 public B2 intj cout constructingB2 j endl B2 cout destructingB2 endl classB3 基類B3聲明 public B3 cout constructingB3 endl B3 cout destructingB3 endl classC publicB2 publicB1 publicB3 public C inta intb intc intd B1 a memberB2 d memberB1 c B2 b private B1memberB1 B2memberB2 B3memberB3 intmain Cobj 1 2 3 4 46 47 例7 6運行結(jié)果 constructingB22constructingB11constructingB3 constructingB13constructingB24constructingB3 destructingB3destructingB2destructingB1destructingB3destructingB1destructingB2 48 同名隱藏規(guī)則 當(dāng)派生類與基類中有同名成員時 若未顯式指定類名 則通過派生類對象使用的是派生類中的同名成員 如果派生類中聲明了與基類成員函數(shù)同名的新函數(shù) 即使函數(shù)的參數(shù)表不同 從基類繼承的同名函數(shù)的所有重載形式也都會被隱藏 如要通過派生類對象訪問基類中被隱藏的同名成員 應(yīng)使用基類名限定 派生類成員的標識與訪問 49 例7 7多繼承同名隱藏舉例 派生類成員的標識與訪問 includeusingnamecpacestd classB1 聲明基類B1 public 外部接口intnV voidfun cout MemberofB1 endl classB2 聲明基類B2 public 外部接口intnV voidfun cout MemberofB2 endl classD1 publicB1 publicB2 public intnV 同名數(shù)據(jù)成員voidfun cout MemberofD1 endl 同名函數(shù)成員 intmain D1d1 d1 nV 1 對象名 成員名標識 訪問D1類成員d1 fun d1 B1 nV 2 作用域分辨符標識 訪問基類B1成員d1 B1 fun d1 B2 nV 3 作用域分辨符標識 訪問基類B2成員d1 B2 fun 50 51 二義性問題 在多繼承時 基類之間出現(xiàn)同名成員時 將出現(xiàn)訪問時的二義性 不確定性 用類名限定 或同名隱藏規(guī)則來解決 當(dāng)派生類從多個基類派生 而這些基類又從同一個基類派生 則在訪問此共同基類中的成員時 將產(chǎn)生二義性 采用虛基類來解決 派生類成員的標識與訪問 52 二義性問題舉例 一 classA public voidf classB public voidf voidg classC publicA piblicB public voidg voidh 如果聲明 Cc1 則c1 f 具有二義性而c1 g 無二義性 同名隱藏 派生類成員的標識與訪問 53 二義性的解決方法 解決方法一 用類名來限定c1 A f 或c1 B f 解決方法二 同名隱藏在C中聲明一個同名成員函數(shù)f 在f 中根據(jù)需要調(diào)用A f 或B f 派生類成員的標識與訪問 54 二義性問題舉例 二 classB public intb classB1 publicB private intb1 classB2 publicB private intb2 classC publicB1 publicB2 public intf private intd 派生類成員的標識與訪問 派生類C的對象的存儲結(jié)構(gòu)示意圖 有二義性 Cc c bc B b 無二義性 c B1 bc B2 b 55 56 虛基類 虛基類的引入用于有共同基類的場合聲明以virtual修飾說明基類例 classB1 virtualpublicB作用主要用來解決多繼承時可能發(fā)生的對同一基類繼承多次而產(chǎn)生的二義性問題 為最遠的派生類提供惟一的基類成員 而不重復(fù)產(chǎn)生多次拷貝注意 在第一級繼承時就要將共同基類設(shè)計為虛基類 57 虛基類舉例 classB private intb classB1 virtualpublicB private intb1 classB2 virtualpublicB private intb2 classC publicB1 publicB2 private floatd 下面的訪問是正確的 Ccobj cobj b 虛基類 虛基類的派生類對象存儲結(jié)構(gòu)示意圖 58 59 例7 8虛基類舉例 虛基類 60 includeusingnamecpacestd classB0 聲明基類B0 public 外部接口intnV voidfun cout MemberofB0 endl classB1 virtualpublicB0 B0為虛基類 派生B1類 public 新增外部接口intnV1 classB2 virtualpublicB0 B0為虛基類 派生B2類 public 新增外部接口intnV2 61 classD1 publicB1 publicB2 派生類D1聲明 public 新增外部接口intnVd voidfund cout Membero
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 西藏清代糧倉管理辦法
- 自貢養(yǎng)殖大棚管理辦法
- 逆向思維訓(xùn)練培訓(xùn)課件
- 肝膽微課護理課件
- 肝病護理課件
- 甘肅高考模擬數(shù)學(xué)試卷
- 肝病中醫(yī)護理課件
- 福建省泉州初三數(shù)學(xué)試卷
- 東營三模數(shù)學(xué)試卷
- 課件制作的培訓(xùn)總結(jié)
- 浙江杭州市2024-2025學(xué)年高一下學(xué)期6月期末考試英語試題及答案
- 喘息性支氣管肺炎的護理查房
- 新型電極材料成本控制-洞察及研究
- 2025年初中數(shù)學(xué)知識點測試題及答案
- 小學(xué)生集體活動安全課件
- 2025-2030年中國高爾夫產(chǎn)品行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 山東威海經(jīng)發(fā)投資控股集團有限公司及下屬子公司招聘筆試題庫2025
- 新能源汽車充電樁建設(shè)方案及流程
- 2025-2030年中國人乳寡糖(HMO)行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 動火工作方案
- 成都市2022級(2025屆)高中畢業(yè)班摸底測試(零診)數(shù)學(xué)試卷(含答案)
評論
0/150
提交評論