C/C++ 公有繼承、保護繼承和私有繼承的對比詳解。本站提示廣大學習愛好者:(C/C++ 公有繼承、保護繼承和私有繼承的對比詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C/C++ 公有繼承、保護繼承和私有繼承的對比詳解正文
C/C++ 公有繼承、保護繼承和私有繼承的區別
在c++的繼承控制中,有三種不同的控制權限,分別是public、protected和private。定義派生類時,若不顯示加上這三個關鍵字,就會使用默認的方式,用struct定義的類是默認public繼承,class定義的類是默認private繼承。這和Java有很大的不同,Java默認使用public繼承,而且只有公有繼承。
1.使用public繼承時,派生類內部可以訪問基類中public和protected成員,但是類外只能通過派生類的對象訪問基類的public成員。
(1)基類的public成員在派生類中依然是public的。
(2)基類中的protected成員在派生類中依然是protected的。
(3)基類中的private成員在派生類中不可訪問。
2.使用protected繼承時,派生類內部可以訪問基類中public和protected成員,並且類外也不能通過派生類的對象訪問基類的成員(可以在派生類中添加公有成員函數接口間接訪問基類中的public和protected成員)。
(1)基類的public成員在派生類中變為protected成員。
(2)基類的protected成員在派生類中依然是protected成員。
(3)基類中的private成員在派生類中不可訪問。
3.使用private繼承時,派生類內部可以訪問基類中public和protected成員,並且類外也不能通過派生類的對象訪問基類的成員(可以在派生類中添加公有成員函數接口間接訪問基類中的public和protected成員)。
(1)基類的public成員在派生類中變成private成員。
(2)基類的protected成員在派生類中變成private成員。
(3)基類的private成員在派生類中不可訪問。
為了便於理解,我們用一個表格來說明這幾種控制符使用的情況:
派 生 方 式 基類的public成員 基類的protected成員 基類的private成員 public派生 還是public成員 變為protected成員 不可見 protected派生 變成protected成員 還是protected成員 不可見 private派生 變為private成員 變成private成員 不可見
下面用代碼簡單敘述
#include <iostream> class Base { public: int public_a; virtual void test() = 0; protected: int protected_a; private: int private_a; }; //公有繼承 class PublicDerived : public Base { public: virtual void test() { public_a = 1; //public_a public繼承後還是public類型 protected_a = 2; //protected_a 還是protected類型 //private_a = 3; //派生類不可訪問基類私有成員 } }; //保護繼承 class ProtectedDerived : protected Base { public: virtual void test() { public_a = 1; //public_a protected繼承後變為protected類型 protected_a = 2; //protected_a 還是protected類型 //private_a = 3; //派生類不可訪問基類私有成員 } }; //私有繼承 class PrivateDerived : private Base { public: virtual void test() { public_a = 1; //public_a private繼承後變為private類型 protected_a = 2; //protected_a private繼承後變為private類型 //private_a = 3; //派生類不可訪問基類私有成員 } };
在c++中public繼承是is-a的關系。也就說適用於基類身上的一定也適用於派生類身上,因為每一個派生類對象也都是一個基類對象。派生類對象轉換為基類對象在需要的時候是可以自動轉化的。
其實,protected和private派生後的派生類不是基類的子類,因為此派生類不能做基類所能做的所有事情。我們看看下面的代碼
#include <iostream> class Person { public: Person(){}; void eat() {std::cout << "eat\n";} }; //公有繼承 class PublicStudent : public Person { public: PublicStudent() {} void study() {std::cout << "study\n";} }; //保護繼承 class ProtectedStudent : protected Person { public: ProtectedStudent() {} void study() {std::cout << "study\n";} }; //私有繼承 class PrivateStudent : private Person { public: PrivateStudent() {} void study() {std::cout << "study\n";} }; void func_test(Person &p) { p.eat(); } int main() { PublicStudent public_s; ProtectedStudent protected_s; PrivateStudent private_s; func_test(public_s); //正確,公有繼承時,派生類可以做基類的所有事情 func_test(protected_s); //出錯,保護繼承時,派生類不能做基類的所有事情 func_test(private_s); //出錯,私有繼承時,派生類不可以做基類的所有事情 system("pause"); return 0; }
func_test()需要一個Person類型的對象,在調用func_test(public_s)時實際傳遞的是PublicStudent對象,因為PublicStudent共有繼承Person類,所以PublicStudent對象可以使用Person類中所有的公有成員,也就是說基類對象可以做的事,公有繼承的派生類對象照樣可以做。而ProtectedStudent和PrivateStudent都是非公有有繼承,他們的對象不可以直接訪問Person類的成員。但是在他們派生類的對象空間中是包含基類的的對象,只是無法讓他們公開訪問。從上面的代碼可以看出來,protected繼承和private繼承的派生類已經不是基類的子類了。
寫了這麼多,其實非公有繼承很少遇到。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!