C++ 語(yǔ)言程序設(shè)計(jì)(清華大學(xué)鄭莉) (7).ppt_第1頁(yè)
C++ 語(yǔ)言程序設(shè)計(jì)(清華大學(xué)鄭莉) (7).ppt_第2頁(yè)
C++ 語(yǔ)言程序設(shè)計(jì)(清華大學(xué)鄭莉) (7).ppt_第3頁(yè)
C++ 語(yǔ)言程序設(shè)計(jì)(清華大學(xué)鄭莉) (7).ppt_第4頁(yè)
C++ 語(yǔ)言程序設(shè)計(jì)(清華大學(xué)鄭莉) (7).ppt_第5頁(yè)
已閱讀5頁(yè),還剩63頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1 第七章繼承與派生 清華大學(xué)鄭莉 C 語(yǔ)言程序設(shè)計(jì) 2 本章主要內(nèi)容 類(lèi)的繼承類(lèi)成員的訪(fǎng)問(wèn)控制單繼承與多繼承派生類(lèi)的構(gòu)造 析構(gòu)函數(shù)類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 3 類(lèi)的繼承與派生 保持已有類(lèi)的特性而構(gòu)造新類(lèi)的過(guò)程稱(chēng)為繼承 在已有類(lèi)的基礎(chǔ)上新增自己的特性而產(chǎn)生新類(lèi)的過(guò)程稱(chēng)為派生 被繼承的已有類(lèi)稱(chēng)為基類(lèi) 或父類(lèi) 派生出的新類(lèi)稱(chēng)為派生類(lèi) 4 繼承與派生問(wèn)題舉例 類(lèi)的繼承與派生 5 繼承與派生問(wèn)題舉例 類(lèi)的繼承與派生 貓科 6 繼承與派生問(wèn)題舉例 類(lèi)的繼承與派生 7 繼承與派生問(wèn)題舉例 類(lèi)的繼承與派生 8 繼承與派生的目的 繼承的目的 實(shí)現(xiàn)代碼重用 派生的目的 當(dāng)新的問(wèn)題出現(xiàn) 原有程序無(wú)法解決 或不能完全解決 時(shí) 需要對(duì)原有程序進(jìn)行改造 類(lèi)的繼承與派生 9 派生類(lèi)的聲明 class派生類(lèi)名 繼承方式基類(lèi)名 成員聲明 類(lèi)的繼承與派生 10 繼承方式 不同繼承方式的影響主要體現(xiàn)在 派生類(lèi)成員對(duì)基類(lèi)成員的訪(fǎng)問(wèn)權(quán)限通過(guò)派生類(lèi)對(duì)象對(duì)基類(lèi)成員的訪(fǎng)問(wèn)權(quán)限三種繼承方式公有繼承私有繼承保護(hù)繼承 類(lèi)成員的訪(fǎng)問(wèn)控制 11 公有繼承 public 基類(lèi)的public和protected成員的訪(fǎng)問(wèn)屬性在派生類(lèi)中保持不變 但基類(lèi)的private成員不可直接訪(fǎng)問(wèn) 派生類(lèi)中的成員函數(shù)可以直接訪(fǎng)問(wèn)基類(lèi)中的public和protected成員 但不能直接訪(fǎng)問(wèn)基類(lèi)的private成員 通過(guò)派生類(lèi)的對(duì)象只能訪(fǎng)問(wèn)基類(lèi)的public成員 類(lèi)成員的訪(fǎng)問(wèn)控制 12 例7 1公有繼承舉例 classPoint 基類(lèi)Point類(lèi)的聲明 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 類(lèi)成員的訪(fǎng)問(wèn)控制 classRectangle publicPoint 派生類(lèi)聲明 public 新增公有函數(shù)成員voidInitR floatx floaty floatw floath InitP x y W w H h 調(diào)用基類(lèi)公有成員函數(shù)floatGetH returnH floatGetW returnW private 新增私有數(shù)據(jù)成員floatW H 13 include includeusingnamecpacestd intmain Rectanglerect rect InitR 2 3 20 10 通過(guò)派生類(lèi)對(duì)象訪(fǎng)問(wèn)基類(lèi)公有成員rect Move 3 2 cout rect GetX rect GetY rect GetH rect GetW endl return0 14 15 16 私有繼承 private 基類(lèi)的public和protected成員都以private身份出現(xiàn)在派生類(lèi)中 但基類(lèi)的private成員不可直接訪(fǎng)問(wèn) 派生類(lèi)中的成員函數(shù)可以直接訪(fǎng)問(wèn)基類(lèi)中的public和protected成員 但不能直接訪(fǎng)問(wèn)基類(lèi)的private成員 通過(guò)派生類(lèi)的對(duì)象不能直接訪(fǎng)問(wèn)基類(lèi)中的任何成員 類(lèi)成員的訪(fǎng)問(wèn)控制 17 例7 2私有繼承舉例 classRectangle privatePoint 派生類(lèi)聲明 public 新增外部接口voidInitR floatx floaty floatw floath InitP x y W w H h 訪(fǎng)問(wèn)基類(lèi)公有成員voidMove floatxOff floatyOff Point Move xOff yOff floatGetX returnPoint GetX floatGetY returnPoint GetY floatGetH returnH floatGetW returnW private 新增私有數(shù)據(jù)floatW H 類(lèi)成員的訪(fǎng)問(wèn)控制 include includeusingnamecpacestd intmain 通過(guò)派生類(lèi)對(duì)象只能訪(fǎng)問(wèn)本類(lèi)成員Rectanglerect rect InitR 2 3 20 10 rect Move 3 2 cout rect GetX rect GetY rect GetH rect GetW endl return0 18 19 保護(hù)繼承 protected 基類(lèi)的public和protected成員都以protected身份出現(xiàn)在派生類(lèi)中 但基類(lèi)的private成員不可直接訪(fǎng)問(wèn) 派生類(lèi)中的成員函數(shù)可以直接訪(fǎng)問(wèn)基類(lèi)中的public和protected成員 但不能直接訪(fǎng)問(wèn)基類(lèi)的private成員 通過(guò)派生類(lèi)的對(duì)象不能直接訪(fǎng)問(wèn)基類(lèi)中的任何成員 類(lèi)成員的訪(fǎng)問(wèn)控制 20 protected成員的特點(diǎn)與作用 對(duì)建立其所在類(lèi)對(duì)象的模塊來(lái)說(shuō) 它與private成員的性質(zhì)相同 對(duì)于其派生類(lèi)來(lái)說(shuō) 它與public成員的性質(zhì)相同 既實(shí)現(xiàn)了數(shù)據(jù)隱藏 又方便繼承 實(shí)現(xiàn)代碼重用 類(lèi)成員的訪(fǎng)問(wèn)控制 21 例7 3protected成員舉例 classA protected intx intmain Aa a x 5 錯(cuò)誤 類(lèi)成員的訪(fǎng)問(wèn)控制 classA protected intx classB publicA public voidFunction voidB Function x 5 正確 22 23 類(lèi)型兼容規(guī)則 一個(gè)公有派生類(lèi)的對(duì)象在使用上可以被當(dāng)作基類(lèi)的對(duì)象 反之則禁止 具體表現(xiàn)在 派生類(lèi)的對(duì)象可以被賦值給基類(lèi)對(duì)象 派生類(lèi)的對(duì)象可以初始化基類(lèi)的引用 指向基類(lèi)的指針也可以指向派生類(lèi) 通過(guò)基類(lèi)對(duì)象名 指針只能使用從基類(lèi)繼承的成員 類(lèi)型兼容 24 例7 4類(lèi)型兼容規(guī)則舉例 通用顯示程序的幻想 includeusingnamecpacestd classB0 基類(lèi)B0聲明 public voiddisplay cout B0 display endl 公有成員函數(shù) 類(lèi)型兼容 classB1 publicB0 public voiddisplay coutdisplay 對(duì)象指針 成員名 25 intmain 主函數(shù) B0b0 聲明B0類(lèi)對(duì)象B1b1 聲明B1類(lèi)對(duì)象D1d1 聲明D1類(lèi)對(duì)象B0 p 聲明B0類(lèi)指針p 運(yùn)行結(jié)果 B0 display B0 display B0 display 26 27 基類(lèi)與派生類(lèi)的對(duì)應(yīng)關(guān)系 單繼承派生類(lèi)只從一個(gè)基類(lèi)派生 多繼承派生類(lèi)從多個(gè)基類(lèi)派生 多重派生由一個(gè)基類(lèi)派生出多個(gè)不同的派生類(lèi) 多層派生派生類(lèi)又作為基類(lèi) 繼續(xù)派生新的類(lèi) 單繼承與多繼承 28 多繼承時(shí)派生類(lèi)的聲明 class派生類(lèi)名 繼承方式1基類(lèi)名1 繼承方式2基類(lèi)名2 成員聲明 注意 每一個(gè) 繼承方式 只用于限制對(duì)緊隨其后之基類(lèi)的繼承 單繼承與多繼承 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 派生類(lèi)成員直接訪(fǎng)問(wèn)基類(lèi)的 公有成員setA x setB y c z 其他函數(shù)實(shí)現(xiàn)略 intmain Cobj obj setA 5 obj showA obj setC 6 7 9 obj showC obj setB 6 錯(cuò)誤 obj showB 錯(cuò)誤return0 30 31 繼承時(shí)的構(gòu)造函數(shù) 派生類(lèi)中需要聲明自己的構(gòu)造函數(shù) 聲明構(gòu)造函數(shù)時(shí) 只需要對(duì)本類(lèi)中新增成員進(jìn)行初始化 對(duì)繼承來(lái)的基類(lèi)成員的初始化 自動(dòng)調(diào)用基類(lèi)構(gòu)造函數(shù)完成 派生類(lèi)的構(gòu)造函數(shù)需要給基類(lèi)的構(gòu)造函數(shù)傳遞參數(shù) 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 32 單一繼承時(shí)的構(gòu)造函數(shù) 派生類(lèi)名 派生類(lèi)名 基類(lèi)所需的形參 本類(lèi)成員所需的形參 基類(lèi)名 參數(shù)表 本類(lèi)成員初始化賦值語(yǔ)句 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 33 單一繼承時(shí)的構(gòu)造函數(shù)舉例 includeusingnamespacestd classB public B B inti B voidPrint const private intb 派生類(lèi)的構(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 派生類(lèi)與基類(lèi)的構(gòu)造函數(shù) 當(dāng)基類(lèi)中聲明有默認(rèn)形式的構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時(shí) 派生類(lèi)構(gòu)造函數(shù)可以不向基類(lèi)構(gòu)造函數(shù)傳遞參數(shù) 若基類(lèi)中未聲明構(gòu)造函數(shù) 派生類(lèi)中也可以不聲明 全采用默認(rèn)形式構(gòu)造函數(shù) 當(dāng)基類(lèi)聲明有帶形參的構(gòu)造函數(shù)時(shí) 派生類(lèi)也應(yīng)聲明帶形參的構(gòu)造函數(shù) 并將參數(shù)傳遞給基類(lèi)構(gòu)造函數(shù) 程序舉例constrc base cpp 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 38 多繼承時(shí)的構(gòu)造函數(shù) 派生類(lèi)名 派生類(lèi)名 基類(lèi)1形參 基類(lèi)2形參 基類(lèi)n形參 本類(lèi)形參 基類(lèi)名1 參數(shù) 基類(lèi)名2 參數(shù) 基類(lèi)名n 參數(shù) 本類(lèi)成員初始化賦值語(yǔ)句 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 39 多繼承且有內(nèi)嵌對(duì)象時(shí)的構(gòu)造函數(shù) 派生類(lèi)名 派生類(lèi)名 基類(lèi)1形參 基類(lèi)2形參 基類(lèi)n形參 本類(lèi)形參 基類(lèi)名1 參數(shù) 基類(lèi)名2 參數(shù) 基類(lèi)名n 參數(shù) 對(duì)象數(shù)據(jù)成員的初始化 本類(lèi)成員初始化賦值語(yǔ)句 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 40 構(gòu)造函數(shù)的調(diào)用順序 1 調(diào)用基類(lèi)構(gòu)造函數(shù) 調(diào)用順序按照它們被繼承時(shí)聲明的順序 從左向右 2 調(diào)用成員對(duì)象的構(gòu)造函數(shù) 調(diào)用順序按照它們?cè)陬?lèi)中聲明的順序 3 派生類(lèi)的構(gòu)造函數(shù)體中的內(nèi)容 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 41 例7 5派生類(lèi)構(gòu)造函數(shù)舉例 includeusingnamecpacestd classB1 基類(lèi)B1 構(gòu)造函數(shù)有參數(shù) public B1 inti cout constructingB1 i endl classB2 基類(lèi)B2 構(gòu)造函數(shù)有參數(shù) public B2 intj cout constructingB2 j endl classB3 基類(lèi)B3 構(gòu)造函數(shù)無(wú)參數(shù) public B3 cout constructingB3 endl 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) classC publicB2 publicB1 publicB3 public 派生類(lèi)的公有成員C inta intb intc intd B1 a memberB2 d memberB1 c B2 b private 派生類(lèi)的私有對(duì)象成員B1memberB1 B2memberB2 B3memberB3 intmain Cobj 1 2 3 4 運(yùn)行結(jié)果 constructingB22constructingB11constructingB3 constructingB13constructingB24constructingB3 42 43 拷貝構(gòu)造函數(shù) 若建立派生類(lèi)對(duì)象時(shí)調(diào)用默認(rèn)拷貝構(gòu)造函數(shù) 則編譯器將自動(dòng)調(diào)用基類(lèi)的默認(rèn)拷貝構(gòu)造函數(shù) 若編寫(xiě)派生類(lèi)的拷貝構(gòu)造函數(shù) 則需要為基類(lèi)相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù) 例如 C C C c1 B c1 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 44 繼承時(shí)的析構(gòu)函數(shù) 析構(gòu)函數(shù)也不被繼承 派生類(lèi)自行聲明聲明方法與一般 無(wú)繼承關(guān)系時(shí) 類(lèi)的析構(gòu)函數(shù)相同 不需要顯式地調(diào)用基類(lèi)的析構(gòu)函數(shù) 系統(tǒng)會(huì)自動(dòng)隱式調(diào)用 析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) 45 例7 6派生類(lèi)析構(gòu)函數(shù)舉例 派生類(lèi)的構(gòu)造 析構(gòu)函數(shù) includeusingnamecpacestd classB1 基類(lèi)B1聲明 public B1 inti cout constructingB1 i endl B1 cout destructingB1 endl classB2 基類(lèi)B2聲明 public B2 intj cout constructingB2 j endl B2 cout destructingB2 endl classB3 基類(lèi)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運(yùn)行結(jié)果 constructingB22constructingB11constructingB3 constructingB13constructingB24constructingB3 destructingB3destructingB2destructingB1destructingB3destructingB1destructingB2 48 同名隱藏規(guī)則 當(dāng)派生類(lèi)與基類(lèi)中有同名成員時(shí) 若未顯式指定類(lèi)名 則通過(guò)派生類(lèi)對(duì)象使用的是派生類(lèi)中的同名成員 如果派生類(lèi)中聲明了與基類(lèi)成員函數(shù)同名的新函數(shù) 即使函數(shù)的參數(shù)表不同 從基類(lèi)繼承的同名函數(shù)的所有重載形式也都會(huì)被隱藏 如要通過(guò)派生類(lèi)對(duì)象訪(fǎng)問(wèn)基類(lèi)中被隱藏的同名成員 應(yīng)使用基類(lèi)名限定 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 49 例7 7多繼承同名隱藏舉例 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) includeusingnamecpacestd classB1 聲明基類(lèi)B1 public 外部接口intnV voidfun cout MemberofB1 endl classB2 聲明基類(lèi)B2 public 外部接口intnV voidfun cout MemberofB2 endl classD1 publicB1 publicB2 public intnV 同名數(shù)據(jù)成員voidfun cout MemberofD1 endl 同名函數(shù)成員 intmain D1d1 d1 nV 1 對(duì)象名 成員名標(biāo)識(shí) 訪(fǎng)問(wèn)D1類(lèi)成員d1 fun d1 B1 nV 2 作用域分辨符標(biāo)識(shí) 訪(fǎng)問(wèn)基類(lèi)B1成員d1 B1 fun d1 B2 nV 3 作用域分辨符標(biāo)識(shí) 訪(fǎng)問(wèn)基類(lèi)B2成員d1 B2 fun 50 51 二義性問(wèn)題 在多繼承時(shí) 基類(lèi)之間出現(xiàn)同名成員時(shí) 將出現(xiàn)訪(fǎng)問(wèn)時(shí)的二義性 不確定性 用類(lèi)名限定 或同名隱藏規(guī)則來(lái)解決 當(dāng)派生類(lèi)從多個(gè)基類(lèi)派生 而這些基類(lèi)又從同一個(gè)基類(lèi)派生 則在訪(fǎng)問(wèn)此共同基類(lèi)中的成員時(shí) 將產(chǎn)生二義性 采用虛基類(lèi)來(lái)解決 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 52 二義性問(wèn)題舉例 一 classA public voidf classB public voidf voidg classC publicA piblicB public voidg voidh 如果聲明 Cc1 則c1 f 具有二義性而c1 g 無(wú)二義性 同名隱藏 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 53 二義性的解決方法 解決方法一 用類(lèi)名來(lái)限定c1 A f 或c1 B f 解決方法二 同名隱藏在C中聲明一個(gè)同名成員函數(shù)f 在f 中根據(jù)需要調(diào)用A f 或B f 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 54 二義性問(wèn)題舉例 二 classB public intb classB1 publicB private intb1 classB2 publicB private intb2 classC publicB1 publicB2 public intf private intd 派生類(lèi)成員的標(biāo)識(shí)與訪(fǎng)問(wèn) 派生類(lèi)C的對(duì)象的存儲(chǔ)結(jié)構(gòu)示意圖 有二義性 Cc c bc B b 無(wú)二義性 c B1 bc B2 b 55 56 虛基類(lèi) 虛基類(lèi)的引入用于有共同基類(lèi)的場(chǎng)合聲明以virtual修飾說(shuō)明基類(lèi)例 classB1 virtualpublicB作用主要用來(lái)解決多繼承時(shí)可能發(fā)生的對(duì)同一基類(lèi)繼承多次而產(chǎn)生的二義性問(wèn)題 為最遠(yuǎn)的派生類(lèi)提供惟一的基類(lèi)成員 而不重復(fù)產(chǎn)生多次拷貝注意 在第一級(jí)繼承時(shí)就要將共同基類(lèi)設(shè)計(jì)為虛基類(lèi) 57 虛基類(lèi)舉例 classB private intb classB1 virtualpublicB private intb1 classB2 virtualpublicB private intb2 classC publicB1 publicB2 private floatd 下面的訪(fǎng)問(wèn)是正確的 Ccobj cobj b 虛基類(lèi) 虛基類(lèi)的派生類(lèi)對(duì)象存儲(chǔ)結(jié)構(gòu)示意圖 58 59 例7 8虛基類(lèi)舉例 虛基類(lèi) 60 includeusingnamecpacestd classB0 聲明基類(lèi)B0 public 外部接口intnV voidfun cout MemberofB0 endl classB1 virtualpublicB0 B0為虛基類(lèi) 派生B1類(lèi) public 新增外部接口intnV1 classB2 virtualpublicB0 B0為虛基類(lèi) 派生B2類(lèi) public 新增外部接口intnV2 61 classD1 publicB1 publicB2 派生類(lèi)D1聲明 public 新增外部接口intnVd voidfund cout Membero

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論