程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++學習摘要之三:繼承和派生

C++學習摘要之三:繼承和派生

編輯:關於C++

繼承性是面向對象程序設計最重要的機制之一。

1.繼承的概念

所謂繼承 (inheritance)就是利用已有的數據類型定義出新的數據類型。

在繼承關系中,被繼承的類稱為 基類(base class)或父類,而通過繼承關系定義出來的新類則被稱為派生類(derived class)或子類 。

派生類既可以對基類的性質進行擴展又可以對基類進行限制,從而得到更加靈活、適用的可重 用模塊,大大縮短了程序的開發時間。

一個派生類既可以從一個基類派生也可以從多個基類派生 。從一個基類派生稱為單繼承;從多個基類派生稱為多重繼承。

(1)單繼承

單繼承的定 義形式如下:

class 派生類名:訪問方式 基類名

{

派生類中的新成員

};

其中,派生類名是新定義的類名。基類名必須是程序中已有的一個類。

在單繼承中,每個 類可以有多個派生類,但是每個派生類只能有一個基類。

(2)多重繼承

所謂多重繼承是 指派生類從多個基類中派生而來的。

定義多重繼承類的方式如下:

class 派生類名:訪問 方式 基類名1,訪問方式 基類名2……

{

派生類中的新成員

};

從定義格式上來看,多重繼承與單繼承的區別主要是多重繼承的基類多於一個。

(3)訪 問方式

不管在單繼承還是在多重繼承的定義格式中,訪問方式,即繼承方式,可以為public、 private或protected,如果省略,則默認為private方式。

訪問方式為public方式時,這種繼承稱 為公有繼承;

訪問方式為private方式時,這種繼承稱為私有繼承;

訪問方式為protected 方式時,這種繼承稱為保護繼承。

2.派生類的生成過程

在給出了派生類的定義和相應成 員函數的實現代碼後,整個派生類的定義就算完成了,這是就可以利用該類定義相應的對象處理實際問題 了。

由於派生類是在基類的基礎上經過繼承而產生的,所以搞清派生類中到底有哪些成員對於更 好的使用派生類是很重要的。事實上,派生新類經歷了三個步驟:

(1)吸收基類成員

派 生類繼承吸收了基類的全部數據成員以及除了構造函數、析構函數之外的全部函數成員。也就是說,基類 中的構造函數和析構函數使不能繼承到派生類中的。

(2)改造基類成員

對繼承到派生類 中基類成員的改造包括兩個方面:一是基類成員的訪問方式問題,這由派生類定義時的訪問方式來控制; 二是對基類數據成員或成員函數的覆蓋,也就是在派生類中定義了與基類中同名的數據成員或函數成員, 由於作用域不同,於是發生同名覆蓋,基類中的成員就被替換成派生類中的同名成員。

(3)添加 新成員

在派生類中,除了從基類中繼承過來的成員外,還可以根據需要在派生類中添加新的數據 成員和成員函數,以此實現必要的新功能。可以看出,在派生類中可以添加新成員的機制是繼承和派生機 制的核心,保證了派生類在功能上比基類有所發展。

3.繼承方式對基類成員的訪問控制

前面已經分析,派生類繼承和吸收了基類的全部數據成員和除了構造函數、析構函數之外的全部函數成員 ,但這些成員在派生類中的訪問屬性是可以調整的,這是由派生類定義格式中的繼承方式來決定的,也就 是繼承方式控制了基類中具有不同訪問屬性的成員在派生類中的訪問屬性。

由於繼承方式可以有 public、private和protected三種,不同的繼承方式會導致原來具有不同訪問屬性的基類成員在派生類中 的訪問屬性也有所不同。這種訪問包括兩個方面:一是派生類中新增成員對從基類繼承來的成員的訪問; 二是派生類的外部通過派生類的對象從基類繼承來的成員的訪問。

(1)公有繼承

當類的 繼承方式為公有繼承時,基類中public和protected成員的訪問屬性在派生類中不變,而基類private成員 不可訪問。也就是說,基類的public和protected成員在公有繼承方式下分別繼承為派生類的public和 protected成員,派生類中的其他成員可以直接訪問它們,在派生類的外部只能通過派生類的對象訪問從 基類繼承來的public成員。而無論是派生類的成員還是派生類的對象都無法訪問從基類繼承來的private 成員。

(2)私有繼承

當類的繼承方式為私有繼承時,基類中的public和protected成員都 以private成員出現在派生類中,而基類private成員不可訪問。也就是說,基類的public和protected成 員在私有繼承方式下被繼承為派生類的private成員,派生類中的其他成員可以直接訪問它們,但在派生 類的外部無法通過派生類的對象訪問它們。而無論是派生類的成員還是派生類的對象都無法訪問從基類繼 承來的private成員。

可以看出,經過私有繼承後,所有基類的成員都成為派生類的私有成員,如 果進一步派生的話,基類的成員就無法在新的派生類中被訪問。因此,經過私有繼承後,基類的成員再也 無法在以後的派生類中發揮作用,實際是相當於中止了基類功能的繼續派生。

(3)保護方式

當類的繼承方式為保護繼承時,基類中的public和protected成員都以protected成員出現在派生 類中,而基類private成員不可訪問。也就是說,基類的public和protected成員在保護繼承方式下被繼承 為派生類的protected成員,派生類中的其他成員可以直接訪問它們,但在派生類的外部無法通過派生類 的對象訪問它們。而無論是派生類的成員還是派生類的對象都無法訪問從基類繼承來的private成員。

4.派生類的構造函數和析構函數

繼承和派生的機制可以使派生類繼承基類的成員,從而 實現了原有代碼的重用,但是,由於基類的構造函數和析構函數不能繼承,那麼在派生類中,如果對派生 類新增的成員進行初始化,就必須在派生類中根據需要加入新的構造函數,如果對從基類繼承下來的成員 進行初始化,還必須由基類的構造函數來完成,所以需要在派生類中的構造函數,一方面負責調用基類的 構造函數對基類成員進行初始化,另一方面還要負責對基類的構造函數所需要的參數進行必要的設置。

(1)單繼承方式下派生類構造函數的定義

在單繼承方式下,派生類的構造函數的定義格 式如下:

派生類名::派生類構造函數名(形參表):基類構造函數名(參數表)

{

//派生類構造函數的函數體

}

在此定義格式中,派生類構造函數名後面括號內的 參數表中包括參數的類型和參數名,而基類構造函數名後面括號內的參數表中只有參數名而沒有參數類型 ,並且這些參數必須是來源於派生類構造函數名後面括號內的參數。

(2)多重繼承方式下的派生 類構造函數的定義

在多重繼承方式下,派生類的構造函數必須同時負責所有基類構造函數的調用 ,對於派生類構造函數的參數個數必須同時滿足多個基類初始化的需要。所以,在多重繼承方式下,派生 類的構造函數的定義格式如下:

派生類名::派生類構造函數名(參數表):基類名1(參數表1 )基類名2(參數表2)……

{

//派生類構造函數的函數體

}

其 中,第1個參數表中的參數包含了其後的各個參數表中的參數。

(3)派生類構造函數的執行次序

派生類構造函數執行的一般次序為:

1)調用基類構造函數,調用順序按照它們被繼承時 說明的順序(從左到右),而不是按派生類構造函數在初始化表中的次序;

2)調用子對象的構造 函數(如果在派生類中存在子對象的話),調用順序按照它們在類中說明的順序;

3)執行派生類 構造函數的函數題。

當派生類的對象被刪除時,派生類的析構函數被執行。由於基類的析構函數 不能被繼承,因此在執行派生類的析構函數時,基類的析構函數也將被調用。而執行順序是先執行派生類 的析構函數,再執行基類的析構函數,其順序與執行構造函數是的順序正好相反。

5.虛基類

在多重繼承的情況下,派生類具有兩個以上的直接基類,而這些直接基類的一部分或全部又是從 另一個共同基類派生而來的,這些直接基類中從上一級基類繼承來的成員擁有相同的名稱,在派生類的對 象中,這些同名成員在內存中同時擁有多個拷貝,如何進行分辨呢?有兩種方法,一是使用作用域運算符 唯一標幟並分別訪問它們;二是將直接基類的共同你基類設置為虛基類。

(1)使用作用域運算符 方法

這種方法就是在需要訪問的成員名前加上直接基類名和作用域運算符“::“。 其格式是:

直接基類名::數據成員名

直接基類名:成員函數名(參數表)

(2) 虛基類的方法

該方法就是將直接基類的共同基類設置為虛基類,即在基類的訪問方式前加上關鍵 字“virtual“,聲明虛基類的格式如下:

class 派生類名:virtual 訪問方式 基類 名

{ //聲明派生類成員};

虛基類雖然被一個派生類間接地多次繼承,但派生類卻只繼承 一份該基類的成員,這樣就避免了在派生類中訪問這些成員時的二義性。

6.虛基類機制下的構造 函數的執行順序

虛基類機制下的構造函數的執行順序與一般多重繼承下的構造函數的執行順序是 不同的,其執行順序如下:

(1)一個類的所有直接基類中,虛基類的構造函數在非虛基類之前調 用;

(2)如果一個類的所有直接基類中有多個虛基類,則這些虛基類的構造函數的執行順序與在 派生類中的說明的次序相同;

(3)若虛基類由非虛基類派生而來,則仍然先調用基類構造函數, 再按照派生類中構造函數的執行順序調用。

相關文章

C++學習摘要之二:構造函數和析構函數

http://www.bianceng.cn/Programming/cplus/200911/12302.htm

C++學習摘要之一:類和對象

http://www.bianceng.cn/Programming/cplus/200911/12301.htm

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved