柚子快報(bào)邀請(qǐng)碼778899分享:【C++】繼承
柚子快報(bào)邀請(qǐng)碼778899分享:【C++】繼承
文章目錄
繼承的介紹基類(lèi)和派生類(lèi)對(duì)象的賦值轉(zhuǎn)換繼承中的作用域派生類(lèi)的默認(rèn)構(gòu)造函數(shù)繼承與友元繼承與靜態(tài)成員復(fù)雜的菱形繼承和菱形虛擬繼承繼承的總結(jié)和反思
繼承的介紹
繼承的概念: 繼承機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用最重要的手段,它允許程序員在保持原有類(lèi)特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,產(chǎn)生新的類(lèi),稱為派生類(lèi)。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu),體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程。以前所接觸的復(fù)用都是函數(shù)復(fù)用,繼承是類(lèi)設(shè)計(jì)層次的復(fù)用。
繼承基類(lèi)成員訪問(wèn)方式的變化 要點(diǎn):
基類(lèi)private成員在派生類(lèi)中不管以什么方式繼承都是不可見(jiàn)的如果要基類(lèi)成員在類(lèi)外不能被訪問(wèn),但是在派生類(lèi)中可以被訪問(wèn),就定義為protected使用關(guān)鍵字class的默認(rèn)繼承方式為private,使用關(guān)鍵字struct的默認(rèn)繼承方式為public,不過(guò),最好顯示的寫(xiě)出繼承方式。在實(shí)際運(yùn)用中一般都使用public繼承,幾乎不使用private/protected繼承。
基類(lèi)和派生類(lèi)對(duì)象的賦值轉(zhuǎn)換
向上轉(zhuǎn)換!
派生類(lèi)的對(duì)象可以賦值給 基類(lèi)的對(duì)象/基類(lèi)的指針/基類(lèi)的引用。這里有個(gè)形象的說(shuō)法叫做切片或者切割,意思就是把基類(lèi)的那一部分切下來(lái)賦值過(guò)去基類(lèi)對(duì)象不能給派生類(lèi)對(duì)象賦值基類(lèi)的指針或者引用可以通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換賦值給派生類(lèi)的指針或者引用。但必須基類(lèi)的指針指向派生類(lèi)對(duì)象時(shí)才是安全的。
繼承中的作用域
在子類(lèi)和父類(lèi)中都有自己的作用域如果子類(lèi)和父類(lèi)有同名成員,那么在訪問(wèn)子類(lèi)的對(duì)應(yīng)同名成員時(shí),會(huì)屏蔽父類(lèi)的同名成員,這種情況叫做隱藏,也叫重定義。注意,如果函數(shù)名相同,函數(shù)參數(shù)不同,構(gòu)成的也是隱藏,而不是重載(重載需要在同一作用域內(nèi))在實(shí)際的繼承體系中最好不要定義實(shí)際的同名成員
派生類(lèi)的默認(rèn)構(gòu)造函數(shù)
派生類(lèi)的構(gòu)造函數(shù)會(huì)調(diào)用基類(lèi)的構(gòu)造函數(shù)對(duì)基類(lèi)的那一部分成員進(jìn)行初始化。如果基類(lèi)沒(méi)有默認(rèn)構(gòu)造函數(shù),那么要在派生類(lèi)構(gòu)造函數(shù)的初始化列表顯式調(diào)用。 派生類(lèi)的拷貝構(gòu)造函數(shù)必須調(diào)用基類(lèi)的拷貝構(gòu)造函數(shù)對(duì)基類(lèi)成員進(jìn)行初始化 派生類(lèi)的賦值重載函數(shù)必須調(diào)用基類(lèi)的賦值重載函數(shù) 派生類(lèi)的析構(gòu)函數(shù)完成后會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)函數(shù)對(duì)基類(lèi)成員進(jìn)行清理 派生類(lèi)對(duì)象的初始化先調(diào)用基類(lèi)的構(gòu)造在調(diào)用派生類(lèi)的構(gòu)造 因?yàn)楹罄m(xù)的一些場(chǎng)景析構(gòu)函數(shù)需要構(gòu)成重寫(xiě),重寫(xiě)的條件就是函數(shù)名相同,編譯器會(huì)將析構(gòu)函數(shù)的函數(shù)名都處理成destructor。所以在不加virtual的情況下,子類(lèi)的析構(gòu)函數(shù)和父類(lèi)的析構(gòu)函數(shù)構(gòu)成隱藏的關(guān)系
繼承與友元
友元關(guān)系不能繼承,也就是說(shuō)父類(lèi)的友元不能訪問(wèn)基類(lèi)的私有和保護(hù)成員。
繼承與靜態(tài)成員
stati成員不能繼承。如果基類(lèi)定義了一個(gè)static成員,則整個(gè)繼承體系只有這一個(gè)成員。無(wú)論后續(xù)派生出多少類(lèi),都只有一個(gè)static成員實(shí)例。
復(fù)雜的菱形繼承和菱形虛擬繼承
菱形繼承存在二義性問(wèn)題和數(shù)據(jù)的冗余問(wèn)題 這樣二義性的問(wèn)題解決了,但數(shù)據(jù)冗余問(wèn)題卻沒(méi)有解決。 使用虛擬繼承的方法可以解決數(shù)據(jù)冗余問(wèn)題。
下面討論虛擬繼承的原理
下面是菱形繼承的虛擬對(duì)象模型:可以分析得出D對(duì)象將A放到了對(duì)象組成的最先,這個(gè)A同時(shí)屬于B和C,那么B和C如何找到公共的A呢?這里是通過(guò)B和C的兩個(gè)指針,指向的一張表。這兩個(gè)指針叫做虛基表指針,這兩個(gè)表叫做虛基表。虛基表中存了偏移量,通過(guò)偏移量可以找到A。
繼承的總結(jié)和反思
1,很多人說(shuō)C++語(yǔ)法復(fù)雜,繼承就是一個(gè)體現(xiàn)。有了多繼承,就有了菱形繼承和菱形虛擬繼承。實(shí)際應(yīng)用中不要設(shè)計(jì)出多繼承和菱形繼承,否則程序在復(fù)雜性和效率上都有一定的損失 2,多繼承可以說(shuō)是C++的缺陷之一,后來(lái)很多的語(yǔ)言都沒(méi)有多繼承,比如Java。 3,繼承和組合
繼承允許你根據(jù)基類(lèi)的實(shí)現(xiàn)來(lái)定義派生類(lèi)的實(shí)現(xiàn)。這種通過(guò)生成派生類(lèi)的復(fù)用通常被稱為“白箱復(fù)用”。術(shù)語(yǔ)“白箱”是相對(duì)可視性而言:在繼承方式中,基類(lèi)的內(nèi)部細(xì)節(jié)對(duì)派生類(lèi)可見(jiàn)?;鶎右欢ǔ绦蚱茐牧嘶?lèi)的封裝,基類(lèi)的改變,對(duì)派生類(lèi)有很大影響。派生類(lèi)和基類(lèi)間的依賴關(guān)系很強(qiáng),耦合度高。對(duì)象組合是類(lèi)繼承之外的另一種復(fù)用選擇。新的更復(fù)雜的接口功能可以通過(guò)組裝或者組合對(duì)象來(lái)獲得。對(duì)象組合要求被組合的對(duì)象具有良好定義的接口。這種復(fù)用的風(fēng)格稱為黑箱復(fù)用,對(duì)象內(nèi)部的細(xì)節(jié)是不可見(jiàn)的。對(duì)象只以“黑箱”的方式出現(xiàn),組合類(lèi)之間沒(méi)有很強(qiáng)的依賴關(guān)系,耦合度低。優(yōu)先使用對(duì)象組合有利于你保持每個(gè)類(lèi)被封裝。實(shí)際進(jìn)程多去用組合。組合的耦合度低,代碼的維護(hù)性好。不過(guò)繼承也有用武之地的,有些關(guān)系適合繼承,另外要實(shí)現(xiàn)多態(tài),也必須要繼承。類(lèi)之間的關(guān)系能用組合就用組合,其次再考慮繼承。
柚子快報(bào)邀請(qǐng)碼778899分享:【C++】繼承
參考鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。