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

2021年7月10日 14:28
imgur
繼承模式和存取權限有什麼關係?private繼承不是讓所有存取權限變成private嗎?為什麼衍生類別依舊可以存取基礎類別?類別開發者和使用者有什麼區分?特殊函式的繼承會和一般函式一樣嗎? 這是一篇中山資工所 江明朝老師 物件導向程式設計課程筆記,如內容有錯,歡迎留言交流~ 還是很困惑嗎?文章裡有答案喔~😎 好讀版(本篇有三個表格,都在好讀版中):
一、繼承 (inheritance) (一)存取權限 成員函式可以『直接』存取自己的所有成員,也就是使用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繼承,只將public權限改為protected,其餘不變;而private繼承,基礎類別的權限全部都變成private。 注意:繼承型態是限制衍生類別使用者的存取權限,而非衍生類別開發者的存取權限! 在繼承中,需要釐清類別使用者與類別開發者,因為繼承的權限限制和使用行為有差。類別開發者是指使用this指標存取者,因此在類別標頭檔 (如:.h檔)和實作檔 (如:.cpp檔)中類別定義內的部分,都可以使用this指標。如果不使用this指標存取,而是用實例化的物件存取,就都視為類別使用者。故在類別定義外或其他檔案 (如:main.cpp)的部分,一定是類別使用者,但在類別定義中的存取行為,也可以是用物件存取的使用者行為。
imgur
(繼承型態與存取權限關係圖) 在private繼承中,直接繼承的衍生類別對上存取權限不變,隔代繼承的衍生類別無法隔代存取,而物件也無法對上存取,因此private繼承無法隔代繼承。在protected繼承中,直接繼承的類別對上存取權限不變,隔代繼承的類別隔代存取權限不變,而物件對上無法存取,因此protected繼承可以隔代繼承。在public繼承中,不影響任何類別或物件的存取權限,因此public繼承可以隔代繼承,也不改變存取權限。 如果不想要隔代繼承且不想要讓使用者使用有對上的存取權限,則可以使用private繼承;如果想隔代繼承且不想要讓使用者使用有對上的存取權限,則可以使用protected繼承;如果想隔代繼承且想要讓使用者使用有對上的存取權限,則可以使用public繼承。 (三)六個特殊函式 如果不知道六個特殊函式,請先看這篇文章的簡介:[筆記]類別、特殊函式、內嵌函式、函式物件|C++ 雖然六個特殊函數都不繼承,但基礎類別特殊函式可被衍生類別成員函式使用,當然衍生類別也會有自己專屬的特殊函式。因此在定義六個特殊函數時,也可以重複使用基礎類別的特殊函數,如果要在body中使用基礎類別特殊函數時,一定要使用base::特殊函數,不然基礎類別會以為特殊函數是自己的,而陷入無限遞迴的窘境,或是找不到這些特殊函數。 大部分的特殊函式都必須自己呼叫基礎類別特殊函式,只有無參數的構建子和解構子會自動呼叫,不過建構子建議還是要自己呼叫,因為多數建構子會帶有參數而解構子不允許帶有參數,故解構子一定會自動呼叫。 衍生類別可以直接使用基礎類別建構子來做基礎類別的初始化,如果是在初始化列呼叫基礎類別建構子,就不需要用::指出scope;而如果在本體中呼叫基礎類別建構子,就需要用::指出scope。其他特殊的函數建構,也是一樣可以重複使用基礎類別的特殊函數。 要注意建構子和解構子的呼叫順序是相反的,建構子會先執行基礎再執行衍生,而解構子會先執行衍生再執行基礎。不過通常比較少客製化解構子,因為我們會避免自己管理記憶體,也就是我們會避免使用到new/delete。 二、相關文章 1. 物件導向程式設計|模擬真實世界的方式|江明朝
江老師物件導向程設,評分、老師、課程簡介。 2. AOOP Homework source code
3. [筆記]109-2高等物件導向程式設計 期中考
4. [筆記]介面與實作、運算子多載、左值右值、參數傳遞、回傳多值|C++
運算子多載如何執行?int a = 10; ++a—;這串程式碼為什麼會出錯?居然跟左值又值有關!左值右值真的是一左一右嗎?參數傳遞中的傳指標和傳參考差在哪邊?C++居然無法回傳多值,那我該怎麼回傳多值? 5. [筆記]陣列與指標|C++
我以為我傳的是陣列,但居然傳的是指標?為什麼我無法回傳陣列?只能回傳指標?所以陣列和指標是什麼關係?指標運算怎麼算?釋放動態記憶體時,指標變數會不會也被釋放? 6. [筆記]類別、特殊函式、內嵌函式、函式物件|C++
程序導向的C語言也能實作物件導向?C語言要如何模擬類別?C struct與C++ struct與C++ class這三者有什麼差別?類別中有哪六個特殊函式?初始化和賦值有什麼差別?內嵌函式和巨集很像?物件居然可以拿來當成函式?為什麼C++宣告無參數物件時,不用加()? 7. [筆記]繼承模式與存取權限|C++
繼承模式和存取權限有什麼關係?private繼承不是讓所有存取權限變成private嗎?為什麼衍生類別依舊可以存取基礎類別?類別開發者和使用者有什麼區分?特殊函式的繼承會和一般函式一樣嗎? 8. [筆記]多型與繼承的關係|C++
多型的出現是為了要解決什麼問題?多型觸發的條件是什麼?為什麼多型要和繼承一起使用?多型能保有繼承的優點嗎?多型比繼承又多了什麼功能?特殊函式也能多型嗎? 9. [筆記]static / const成員資料與函式|C++
non-const static成員資料無法在類別內初始化,也無法使用初始化列,那到底該如何初始化?static成員是什麼概念?可以將自己宣告為自己的成員資料嗎?如果可以,該如何實現?如果不行,會發生什麼問題? 10. [筆記]夥伴函式與類別、不夠朋友問題|C++
夥伴函式和成員函式差在哪裡?為什麼輸入/輸出的多載運算子一定要為夥伴函式?如果A類別把B函式當作夥伴,但B函式的參數中沒有A類別,顯然這個B不把A當夥伴,就會造成main()無法找到B函式。
愛心
6
留言 0
文章資訊
87 篇文章340 人追蹤