追蹤

宗宗大學

喜歡關注科學、哲學、社會、政治、教育,未來想當一位抱著理想的科學家,期許社會能夠進步。

[筆記]繼承模式與存取權限|C++


繼承模式和存取權限有什麼關係?private繼承不是讓所有存取權限變成private嗎?為什麼衍生類別依舊可以存取基礎類別?類別開發者和使用者有什麼區分?特殊函式的繼承會和一般函式一樣嗎?

這是一篇中山資工所 江明朝老師 物件導向程式設計課程筆記,如內容有錯,歡迎留言交流~

還是很困惑嗎?文章裡有答案喔~😎

一、繼承 (inheritance)

(一)存取權限

public, protected, private的存取權限:

 

成員函式

夥伴函式

非成員函式(使用者)

Public 成員

O

O*

O*

Protected成員

O

O*

X

Private成員

O

O*

X

成員函式可以『直接』存取自己的所有成員,也就是使用this指標;但非成員要『間接』存取他類的成員,夥伴函式 (friend function)也是非成員函數,故也要間接存取。非成員函式必須先實例化他類物件,且透過這個物件去存取此物件內的成員,在尚未實例化前,是不可能存取任何成員的,除非是static物件。

重要的資料建議不要宣告為protected,因為public / protected繼承的衍生類別 (derived class)的成員函式可以直接使用基礎類別 (base class)的protected資料。除非基礎類別和衍生類別關係非常密切,不然建議用public的set或get函式間接存取這些重要資料。

(二)繼承模式與存取權限

不果不寫繼承模式,則class預設為private;struct預設為public,但實務上建議還是寫清楚繼承模式。

class derivedMulti : public base1, base2 //非常危險的寫法,因為這裡的base2是private!盡量寫public base1, private base2

基礎類別成員權限 \ 繼承模式

public 繼承

protected繼承

private繼承

public 權限

public

protected

private

protected權限

protected

protected

private

private權限

private

private

private

對於衍生類別來說,如果是public繼承,基礎類別的權限不變;protected繼承,只將public權限改為protected,其餘不變;而private繼承,基礎類別的權限全部都變成private。

注意:繼承型態是限制衍生類別使用者的存取權限,而非衍生類別開發者的存取權限!

在繼承中,需要釐清類別使用者與類別開發者,因為繼承的權限限制和使用行為有差。類別開發者是指使用this指標存取者,因此在類別標頭檔 (如:.h檔)和實作檔 (如:.cpp檔)中類別定義內的部分,都可以使用this指標。如果不使用this指標存取,而是用實例化的物件存取,就都視為類別使用者故在類別定義外或其他檔案 (如:main.cpp)的部分,一定是類別使用者,但在類別定義中的存取行為,也可以是用物件存取的使用者行為。

繼承型態與存取權限關係圖

在private繼承中,直接繼承的衍生類別對上存取權限不變,隔代繼承的衍生類別無法隔代存取,而物件也無法對上存取,因此private繼承無法隔代繼承。在protected繼承中,直接繼承的類別對上存取權限不變,隔代繼承的類別隔代存取權限不變,而物件對上無法存取,因此protected繼承可以隔代繼承。在public繼承中,不影響任何類別或物件的存取權限,因此public繼承可以隔代繼承,也不改變存取權限。

 

直接繼承

隔代繼承

物件對上存取

Private 繼承

O

X

X

Protected 繼承

O

O

X

Public 繼承

O

O

O

如果不想要隔代繼承且不想要讓使用者使用有對上的存取權限,則可以使用private繼承;如果想隔代繼承且不想要讓使用者使用有對上的存取權限,則可以使用protected繼承;如果想隔代繼承且想要讓使用者使用有對上的存取權限,則可以使用public繼承。

(三)六個特殊函式

如果不知道六個特殊函式,請先看這篇文章的簡介:[筆記]類別、特殊函式、內嵌函式、函式物件|C++

雖然六個特殊函數都不繼承,但基礎類別特殊函式可被衍生類別成員函式使用,當然衍生類別也會有自己專屬的特殊函式。因此在定義六個特殊函數時,也可以重複使用基礎類別的特殊函數,如果要在body中使用基礎類別特殊函數時,一定要使用base::特殊函數,不然基礎類別會以為特殊函數是自己的,而陷入無限遞迴的窘境,或是找不到這些特殊函數。

大部分的特殊函式都必須自己呼叫基礎類別特殊函式,只有無參數的構建子和解構子會自動呼叫,不過建構子建議還是要自己呼叫,因為多數建構子會帶有參數而解構子不允許帶有參數,故解構子一定會自動呼叫。

衍生類別可以直接使用基礎類別建構子來做基礎類別的初始化,如果是在初始化列呼叫基礎類別建構子,就不需要用::指出scope;而如果在本體中呼叫基礎類別建構子,就需要用::指出scope。其他特殊的函數建構,也是一樣可以重複使用基礎類別的特殊函數。

要注意建構子和解構子的呼叫順序是相反的,建構子會先執行基礎再執行衍生,而解構子會先執行衍生再執行基礎。不過通常比較少客製化解構子,因為我們會避免自己管理記憶體,也就是我們會避免使用到new/delete。

二、相關文章

  1. 物件導向程式設計|模擬真實世界的方式|江明朝
  2. AOOP Homework source code
  3. [筆記]109-2高等物件導向程式設計 期中考
  4. [筆記]介面與實作、運算子多載、左值右值、參數傳遞、回傳多值|C++
  5. [筆記]陣列與指標|C++
  6. [筆記]類別、特殊函式、內嵌函式、函式物件|C++
  7. [筆記]繼承模式與存取權限|C++
  8. [筆記]多型與繼承的關係|C++
  9. [筆記]static / const成員資料與函式|C++
  10. [筆記]夥伴函式與類別、不夠朋友問題|C++

本文章發表於:課程

加入85

宗宗大學

國立中山大學 生物科學系

追蹤 384 鼓勵作者

喜歡關注科學、哲學、社會、政治、教育,未來想當一位抱著理想的科學家,期許社會能夠進步。

鼓勵作者

目前持有 Blink Coin: Loading..

選擇禮物


愛心

(Coin 10)

幫高調

(Coin 20)

咖啡

(Coin 30)

掌聲鼓勵

(Coin 40)

崇拜眼神

(Coin 50)

驚呆了

(Coin 60)

神人4ni

(Coin 70)

花束

(Coin 100)

鑽石

(Coin 300)

紅寶石

(Coin 500)

藍寶石

(Coin 1000)

黃寶石

(Coin 3000)


送出鼓勵



發表匿名文章不會出現你的大頭圖與名稱,你可暢所欲言,但文章內容務必遵守「佈告欄使用規範」!


回應

送出回應


想回應這篇文章嗎?也想發表文章嗎?
馬上登入來發表文章、追蹤作者、收藏文章或回應文章吧!

註冊 登入