第十三章 類繼承

類繼承

能夠從已有的類派生出新的類但壮,而派生類繼承了原有類(稱為基類)的特征咸包,包括方法。

1.可以在已有類的基礎(chǔ)上添加功能棒假。

2.可以給類添加數(shù)據(jù)溯职。

3.可以修改類方法的行為。

派生類需要自己的構(gòu)造函數(shù)帽哑。

派生類可以根據(jù)需要添加額外的數(shù)據(jù)成員和成員函數(shù)谜酒。

構(gòu)造函數(shù)必須給新成員(如果有的話)和繼承的成員提供數(shù)據(jù)。

(繼承類型

當一個類派生自基類妻枕,該基類可以被繼承為 public僻族、protectedprivate 幾種類型。繼承類型是通過上面講解的訪問修飾符 access-specifier 來指定的屡谐。

我們幾乎不使用 protectedprivate 繼承述么,通常使用 public 繼承。當使用不同類型的繼承時愕掏,遵循以下幾個規(guī)則:

公有繼承(public):當一個類派生自公有基類時度秘,基類的公有成員也是派生類的公有成員,基類的保護成員也是派生類的保護成員饵撑,基類的私有成員不能直接被派生類訪問剑梳,但是可以通過調(diào)用基類的公有保護成員來訪問唆貌。

保護繼承(protected): 當一個類派生自保護基類時,基類的公有保護成員將成為派生類的保護成員垢乙。

私有繼承(private):當一個類派生自私有基類時锨咙,基類的公有保護成員將成為派生類的私有成員。

無論什么方式繼承追逮,派生類都不能直接訪問基類的私有成員酪刀,而必須通過基類方法進行訪問。

有關(guān)派生類構(gòu)造函數(shù)的要點如下:

1.首先創(chuàng)建基類對象羊壹。

2.派生類構(gòu)造函數(shù)應(yīng)通過成員初始化列表將基類信息傳遞給基類構(gòu)造函數(shù)蓖宦。

3.派生類構(gòu)造函數(shù)應(yīng)初始化派生類新增的數(shù)據(jù)成員。

創(chuàng)建派生類對象時油猫,程序首先調(diào)用基類構(gòu)造函數(shù)稠茂,然后再調(diào)用派生類構(gòu)造函數(shù)∏檠基類構(gòu)造函數(shù)負責(zé)初始化繼承的數(shù)據(jù)成員睬关;派生類構(gòu)造函數(shù)主要用于初始化新增的數(shù)據(jù)成員。派生類的構(gòu)造函數(shù)總是調(diào)用一個基類的構(gòu)造函數(shù)毡证〉绲可以使用初始化列表語法指明要使用的基類構(gòu)造函數(shù),否則將使用默認的基類構(gòu)造函數(shù)料睛。

派生類對象過期時丐箩,程序?qū)⑹紫日{(diào)用派生類析構(gòu)函數(shù),然后在調(diào)用基類析構(gòu)函數(shù)恤煞。

成員初始化列表

派生類構(gòu)造函數(shù)可以使用初始化列表機制將值傳遞給基類構(gòu)造函數(shù)

derived ::derived(type x,type y):base(x,y){

}

其中derived是派生類 base是基類名 x y基類是構(gòu)造函數(shù)變量 屎勘。

同理 基類構(gòu)造函數(shù)也可以這樣做。

基類指針可以在不進行顯式類型轉(zhuǎn)換的情況下指向派生類對象居扒;

基類引用可以在不進行顯式類型轉(zhuǎn)換的情況下指向派生類對象概漱。

然而,基類指針或引用只能用于調(diào)用基類方法喜喂,不能調(diào)用派生類的方法瓤摧。基類聲明的虛函數(shù)除外。

通常,C++要求引用和指針類型與賦給的類型匹配玉吁,但這一規(guī)則對繼承來說是例外照弥。

然而,這種例外只是單向的进副,不可以將基類對象和地址賦給派生類引用和指針产喉。因為派生類指針或引用為基類調(diào)用派生類函數(shù)是沒有意義的。

繼承 is-a關(guān)系

公有繼承是最常用的方式,他建立一種is-a關(guān)系曾沈,即派生類對象也是一個基類對象,可以對基類對象進行的任何操作鸥昏,也可以對派生類對象執(zhí)行塞俱。

多態(tài)公有繼承

有兩種機制可用于實現(xiàn)多態(tài)公有繼承:

1.在派生類中重新定義基類的方法。

2.使用虛方法吏垮。

如果父類子類存在函數(shù)名相同程序?qū)⑹褂脤ο箢愋蛠泶_定使用哪個版本障涯。

如果方法是通過引用或指針而不是對象調(diào)用的,它將確定使哪一種方法膳汪。如果沒有使用關(guān)鍵字virtual唯蝶,程序?qū)⒏鶕?jù)引用類型或指針類型選擇方法;如果使用了virtual遗嗽,程序?qū)⒏鶕?jù)引用或指針指向的對象的類型來選擇方法粘我。

如果要在派生類中重新定義基類的方法,通常應(yīng)將積累方法聲明為虛的痹换。這樣征字,程序?qū)⒏鶕?jù)對象類型而不是引用或指針的類型來選擇方法。為基類聲明一個虛析構(gòu)函數(shù)也是一種慣例娇豫。

虛析構(gòu)函數(shù)可以確保正確的析構(gòu)函數(shù)被調(diào)用(由對象類型來選擇方法而不是指針或引用決定)匙姜。

靜態(tài)聯(lián)編和動態(tài)聯(lián)編

在編譯過程中進行聯(lián)編稱為靜態(tài)聯(lián)編,又稱早期聯(lián)編冯痢。然而氮昧,虛函數(shù)使這項工作變得更困難,使用拿一個函數(shù)是不能在編譯時確定的浦楣,因為編譯器不知道用戶將選擇那種對象袖肥。所以編譯器必須生成能夠在程序運行時選擇正確的虛方法的代碼,這被稱為動態(tài)聯(lián)編椒振,又稱晚期編程昭伸。

將派生類引用或指針轉(zhuǎn)化為基類引用或指針被稱為向上強制轉(zhuǎn)換,這使公有繼承不需要進行顯式類型轉(zhuǎn)換澎迎。

相反的過程——將基類指針或引用轉(zhuǎn)換為派生類指針或引用——成為向下強制轉(zhuǎn)換庐杨。

如果不是顯式類型轉(zhuǎn)換,則向下強制轉(zhuǎn)換是不允許的夹供。原因是is-a關(guān)系通常是不可逆的灵份。

隱式向上強制轉(zhuǎn)換是基類指針或引用可以指向基類對象或派生類對象,因此需要動態(tài)聯(lián)編哮洽。C++使用虛成員函數(shù)來滿足這種需求填渠。

靜態(tài)聯(lián)編的好處 1.效率更高 2.指出不需要重新定義該函數(shù)。這表明,金獎那些語氣將被重新定義的方發(fā)生嗎為虛的氛什。

如果要在派生類中重新定義基類的方法莺葫,則將它設(shè)置為虛方法;否則枪眉,設(shè)置為非虛方法捺檬。

通常編譯器處理虛函數(shù)的方法是:給每個對象添加一個隱藏成員。隱藏成員中保存了一個指向函數(shù)地址數(shù)組的指針贸铜。這個數(shù)組稱為虛函數(shù)表堡纬。虛函數(shù)表中儲存了為類對象進行聲明的虛函數(shù)地址。

使用虛函數(shù)使蒿秦,在內(nèi)存和執(zhí)行速度方面有一定的成本 包括:

1.每個對象都將增大烤镐,增大量為儲存地址的空間;

2.對于每個類棍鳖,編譯器都創(chuàng)建一個虛函數(shù)地址表(數(shù)組)炮叶;

3.對于每個函數(shù)調(diào)用,都需要執(zhí)行意向額外的操作鹊杖,即到表中查找地址悴灵。

1.構(gòu)造函數(shù)不能是虛函數(shù)。創(chuàng)建派生類對象時骂蓖,將調(diào)用派生類的構(gòu)造函數(shù)积瞒,而不是基類的構(gòu)造函數(shù)。

2.析構(gòu)函數(shù)應(yīng)是虛函數(shù)登下,除非類不用做基類茫孔。

否則 當創(chuàng)建基類指針并指向動態(tài)分配的派生類的內(nèi)存時,當釋放這個指針時被芳,將會釋放基類所占的內(nèi)存而不是派生類的缰贝。

所以,通常應(yīng)????給基類提供一個虛析構(gòu)函數(shù)畔濒,即使他并不需要析構(gòu)函數(shù)剩晴。

3.友元不能是虛函數(shù),因為友元不是類成員侵状,而只有成員才能是虛函數(shù)赞弥。可以換種方式使用友元調(diào)用虛成員函數(shù)解決趣兄。

4.重新定義將隱藏方法绽左。

派生類和基類如果出現(xiàn)相同的函數(shù)名,對于派生類的對象來講派生類的函數(shù)將會覆蓋基類的函數(shù)艇潭。

第一 如果重新定義繼承的方法拼窥,應(yīng)確保與原來的原型完全相同戏蔑,但如果返回類型是基類引用或指針,則可以修改為指向派生類的引用或指針(例外)鲁纠。這種特性被稱為返回類型協(xié)變总棵,因為允許返回類型隨類類型的變化而變化。第二房交,如果基類聲明被重載了彻舰,則應(yīng)在派生類中重新定義所有的基類版本。

private和protected之間的區(qū)別只有在基類派生的類中才會表現(xiàn)出來候味。(派生類的成員可以直接訪問基類的保護成員但不能直接訪問基類的私有成員)因此,對于外部世界來說

保護成員的行為與私有成員相似隔心;但對于派生類來說白群,保護成員的行為與公有成員相似。最好對類數(shù)據(jù)成員采用私有訪問控制硬霍,不要使用保護訪問控制帜慢;同時通過基類方法使派生類能夠訪問基類數(shù)據(jù)。

抽象基類

當類聲明中包含純虛函數(shù)時唯卖,則不能創(chuàng)建該類的對象粱玲。這里的理念是,包含純虛函數(shù)的類只用作基類拜轨。

由含有純虛函數(shù)的基類派生出來的類叫做具體類抽减,這表示可以創(chuàng)建這些類型的對象。

在設(shè)計ABC之前橄碾,首先應(yīng)開發(fā)一個模型——指出編程問題所需的類以及他們之間的相互關(guān)系卵沉。一種學(xué)院派思想認為,如果要設(shè)計類繼承層次法牲,則只能將那些不會被用作基類的類設(shè)計為具體的類史汗。這種方法的設(shè)計更清晰,復(fù)雜程度更低拒垃。

ABC要求具體派生類覆蓋其純虛函數(shù)——破事派生類遵循ABC設(shè)置的接口規(guī)則停撞。

繼承和動態(tài)內(nèi)存分配

第一種情況:派生類不使用new

基類聲明中包含了構(gòu)造函數(shù)使用new時需要的特殊方法:析構(gòu)函數(shù)、復(fù)制構(gòu)造函數(shù)悼瓮、重載賦值運算符戈毒。那么派生類就不需要再次定義上述這些。

派生類的析構(gòu)函數(shù)總是要進行一些操作:執(zhí)行自身的代碼后調(diào)用基類析構(gòu)函數(shù)谤牡。

在復(fù)制類成員或繼承的類組件時副硅,則是使用該類的復(fù)制構(gòu)造函數(shù)完成的。

類的默認賦值運算符將自動使用基類的復(fù)制運算符來對基類組件進行賦值翅萤。

第二種情況:派生類使用new

這種情況下恐疲,必須為派生類定義顯式析構(gòu)函數(shù)腊满、賦值構(gòu)造函數(shù)和賦值運算符。

派生類析構(gòu)函數(shù)自動調(diào)用基類的析構(gòu)函數(shù)培己,故其自身的職責(zé)是對派生類構(gòu)造函數(shù)執(zhí)行工作的進行清理碳蛋。

類設(shè)計回顧...

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市省咨,隨后出現(xiàn)的幾起案子肃弟,更是在濱河造成了極大的恐慌,老刑警劉巖零蓉,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笤受,死亡現(xiàn)場離奇詭異,居然都是意外死亡敌蜂,警方通過查閱死者的電腦和手機箩兽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來章喉,“玉大人汗贫,你說我怎么就攤上這事〗胀眩” “怎么了落包?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摊唇。 經(jīng)常有香客問我咐蝇,道長,這世上最難降的妖魔是什么遏片? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任嘹害,我火速辦了婚禮,結(jié)果婚禮上吮便,老公的妹妹穿的比我還像新娘笔呀。我一直安慰自己,他們只是感情好髓需,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布许师。 她就那樣靜靜地躺著,像睡著了一般僚匆。 火紅的嫁衣襯著肌膚如雪微渠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天咧擂,我揣著相機與錄音逞盆,去河邊找鬼。 笑死松申,一個胖子當著我的面吹牛云芦,可吹牛的內(nèi)容都是我干的俯逾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼舅逸,長吁一口氣:“原來是場噩夢啊……” “哼桌肴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起琉历,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤坠七,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旗笔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彪置,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年蝇恶,在試婚紗的時候發(fā)現(xiàn)自己被綠了悉稠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡艘包,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耀盗,到底是詐尸還是另有隱情想虎,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布叛拷,位于F島的核電站舌厨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏忿薇。R本人自食惡果不足惜裙椭,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望署浩。 院中可真熱鬧揉燃,春花似錦、人聲如沸筋栋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弊攘。三九已至抢腐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間襟交,已是汗流浹背迈倍。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捣域,地道東北人啼染。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓宴合,卻偏偏與公主長得像,于是被迫代替她去往敵國和親提完。 傳聞我的和親對象是個殘疾皇子形纺,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 3. 類設(shè)計者工具 3.1 拷貝控制 五種函數(shù)拷貝構(gòu)造函數(shù)拷貝賦值運算符移動構(gòu)造函數(shù)移動賦值運算符析構(gòu)函數(shù)拷貝和移...
    王偵閱讀 1,813評論 0 1
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,523評論 1 51
  • 一個博客,這個博客記錄了他讀這本書的筆記徒欣,總結(jié)得不錯逐样。《深度探索C++對象模型》筆記匯總 1. C++對象模型與內(nèi)...
    Mr希靈閱讀 5,593評論 0 13
  • 戰(zhàn)斗結(jié)束,金軍十萬鐵騎全軍覆沒粗梭,宋軍僅損失不到一百人争便。 蕭太后知道消息大怒,這個軒轅到底是什么來路断医,宋軍的武器為何...
    軒轅宗主閱讀 283評論 0 1