注意:本文有時候會用Visual Studio Code里插件的自動補全功能來展示訪問權限的范圍(當且僅當自動補全范圍等價於對象訪問權限范圍的時候),但是不代表日常使用時只要是出現在自動補全范圍內的可調用對象/成員都是可訪問的。
一,公有繼承
#include<cstdio> #include<iostream> #include<string> #include<algorithm> #include<vector> class Base{ public: int PublicBase; void PublicPrint() {std::cout << "PublicPrint()" << std::endl;} protected: int ProtectedBase; void ProtectedPrint() {std::cout << "ProtectedPrint()" << std::endl;} private: int PrivateBase; void PrivatePrint() {std::cout << "PrivatePrint()" << std::endl;} }; class Derived : public Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; std::cout << ProtectedBase << std::endl; //若要訪問protected的數據成員需要通過派生類里的成員函數訪問 PublicPrint(); ProtectedPrint(); } }; int main(void) { Derived der; der.PublicPrint(); der.PublicBase; //der.ProtectedBase; //不能直接訪問protected數據成員 //der.ProtectedPrint();//意思同上 return 0; }
公有繼承的派生類可以直接訪問基類的public中的數據成員和成員函數,不能直接訪問protected中的數據成員和成員函數,若要訪問protected的數據成員需要通過派生類里的成員函數訪問。基類里的private成員函數及數據成員派生類是沒有訪問權限的。但是我們可以通過間接調用Base::function()來訪問Base類里的private對象。
派生類成員函數的訪問權限一覽:
用戶的訪問權限一覽(非常顯然了):
其實再添幾行代碼,很容易知道Derived的派生類訪問權限(SeconedDerived類是Derived的公有繼承):
二,保護繼承
部分代碼改變如下:
class Derived : protected Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; std::cout << ProtectedBase << std::endl; //若要訪問protected的數據成員需要通過派生類里的成員函數訪問 PublicPrint(); ProtectedPrint(); } };
通常保護繼承的派生類訪問基類成員的權限和公有繼承的派生類訪問基類成員的權限相同,保護繼承的派生類對象訪問父類成員的權限和私有繼承子類對象訪問父類成員的權限相同。(der是Derived實例)
可以看出派生類的訪問權限並沒有什么改變。但是派生類會將所有從基類繼承的成員全部放到protected下。不多贅述。
三,私有繼承
部分代碼改變如下:
class Derived : private Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; } };
私有繼承的過程中,基類中的public和protected屬性的成員在派生類中雖然能被訪問,但是其屬性在派生類中被降級為private,可以當作Derived類的private來訪問。
總結
對於三種繼承,對基類里的private對象處理方式都是一致的,即對派生類都是不可訪問的,但它確實被繼承了,可以通過基類里的函數來訪問。三種繼承的不同之處在於:公有繼承是將基類的public和protected成員直接繼承不改變其屬性(即繼承后依然是public和potected的),保護繼承將基類的public和protected成員直接繼承為派生類的protected成員。而私有繼承則直接將基類的protected和public成員繼承為派生類的private成員。
不難發現,存在着這樣的一個優先級:private > protected > public,舉個例子:
①當繼承方式為public時,派生類里所繼承的成員就是基類里對應成員的屬性(public優先級最低覆蓋不了其它關鍵字)
②當繼承方式為protected時,派生類里所繼承的成員屬性只有public會改變為protected(優先級protected > public,protected能覆蓋public)
③當繼承方式為private時,派生類里所繼承的成員屬性全為private(private優先級最高,相當於覆蓋了其它兩個優先級)。