C/C++ 公有繼承、保護繼承和私有繼承的對比詳解
C/C++ 公有繼承、保護繼承和私有繼承的區(qū)別
在c++的繼承控制中,有三種不同的控制權(quán)限,分別是public、protected和private。定義派生類時,若不顯示加上這三個關(guān)鍵字,就會使用默認的方式,用struct定義的類是默認public繼承,class定義的類是默認private繼承。這和Java有很大的不同,Java默認使用public繼承,而且只有公有繼承。
1.使用public繼承時,派生類內(nèi)部可以訪問基類中public和protected成員,但是類外只能通過派生類的對象訪問基類的public成員。
(1)基類的public成員在派生類中依然是public的。
(2)基類中的protected成員在派生類中依然是protected的。
(3)基類中的private成員在派生類中不可訪問。
2.使用protected繼承時,派生類內(nèi)部可以訪問基類中public和protected成員,并且類外也不能通過派生類的對象訪問基類的成員(可以在派生類中添加公有成員函數(shù)接口間接訪問基類中的public和protected成員)。
(1)基類的public成員在派生類中變?yōu)閜rotected成員。
(2)基類的protected成員在派生類中依然是protected成員。
(3)基類中的private成員在派生類中不可訪問。
3.使用private繼承時,派生類內(nèi)部可以訪問基類中public和protected成員,并且類外也不能通過派生類的對象訪問基類的成員(可以在派生類中添加公有成員函數(shù)接口間接訪問基類中的public和protected成員)。
(1)基類的public成員在派生類中變成private成員。
(2)基類的protected成員在派生類中變成private成員。
(3)基類的private成員在派生類中不可訪問。
為了便于理解,我們用一個表格來說明這幾種控制符使用的情況:
| 派 生 方 式 | 基類的public成員 | 基類的protected成員 | 基類的private成員 |
| public派生 | 還是public成員 | 變?yōu)閜rotected成員 | 不可見 |
| protected派生 | 變成protected成員 | 還是protected成員 | 不可見 |
| private派生 | 變?yōu)閜rivate成員 | 變成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繼承后變?yōu)閜rotected類型
protected_a = 2; //protected_a 還是protected類型
//private_a = 3; //派生類不可訪問基類私有成員
}
};
//私有繼承
class PrivateDerived : private Base {
public:
virtual void test() {
public_a = 1; //public_a private繼承后變?yōu)閜rivate類型
protected_a = 2; //protected_a private繼承后變?yōu)閜rivate類型
//private_a = 3; //派生類不可訪問基類私有成員
}
};
在c++中public繼承是is-a的關(guān)系。也就說適用于基類身上的一定也適用于派生類身上,因為每一個派生類對象也都是一個基類對象。派生類對象轉(zhuǎn)換為基類對象在需要的時候是可以自動轉(zhuǎn)化的。
其實,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類型的對象,在調(diào)用func_test(public_s)時實際傳遞的是PublicStudent對象,因為PublicStudent共有繼承Person類,所以PublicStudent對象可以使用Person類中所有的公有成員,也就是說基類對象可以做的事,公有繼承的派生類對象照樣可以做。而ProtectedStudent和PrivateStudent都是非公有有繼承,他們的對象不可以直接訪問Person類的成員。但是在他們派生類的對象空間中是包含基類的的對象,只是無法讓他們公開訪問。從上面的代碼可以看出來,protected繼承和private繼承的派生類已經(jīng)不是基類的子類了。
寫了這么多,其實非公有繼承很少遇到。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
欄 目:C語言
下一篇:C++中將string類型轉(zhuǎn)化為int類型
本文標(biāo)題:C/C++ 公有繼承、保護繼承和私有繼承的對比詳解
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1741.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現(xiàn)與遞歸實現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點數(shù)在內(nèi)存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結(jié)
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法


