詳解C++ 中的三種繼承方式
public 方式繼承
基類成員對派生類的可見性對派生類來說,基類的公有成員和保護(hù)成員可見,基類的公有成員和保護(hù)成員作為派生類的成員時(shí),它們都保持原有的狀態(tài);基類的私有成員不可見,基類的私有成員仍然是私有的,派生類不可訪問基類中的私有成員。
基類成員對派生類對象的可見性對派生類對象來說,基類的公有成員是可見的,其他成員是不可見的。
所以,在公有繼承時(shí),派生類的對象可以訪問基類中的公有成員,派生類的成員函數(shù)可以訪問基類中的公有成員和保護(hù)成員。
簡單來說,派生類能訪問基類的public, protected成員,繼承過來權(quán)限不變,派生類對象只能訪問基類public成員。
測試代碼如下:
class A
{
private:
int m_data1;
void print1() { cout << "private print1" << endl; }
protected:
int m_data2;
void print2() { cout << "protected print2" << endl; }
public:
A(int x = 1, int y = 2, int z = 3) : m_data1(x), m_data2(y), m_data3(z) {}
int m_data3;
void print3() { cout << "protected print3" << endl; }
};
class B : public A
{
public:
void test_public() {
cout << m_data3 << endl;
print3();
}
void test_protected() {
cout << m_data2 << endl;
print2();
}
void test_private() {
// 下面兩行編譯不過,B類內(nèi)無法訪問父類的私有成員
// cout << m_data1 << endl;
// print1();
}
};
int main(int argc, char const* argv[])
{
B b;
b.test_public();
b.test_protected();
b.test_private();
cout << b.m_data3 << endl;
// cout << b.m_data2 << endl; // 編譯不過,子類對象無法訪問父類protected的成員
// cout << b.m_data1 << endl; // 編譯不過,子類對象無法訪問父類private的成員
return 0;
}
private 方式繼承
基類成員對其對象的可見性與一般類及其對象的可見性相同,公有成員可見,其他成員不可見
基類成員對派生類的可見性對派生類來說,基類的公有成員和保護(hù)成員是可見的,基類的公有成員和保護(hù)成員都作為派生類的私有成員,并且不能被這個派生類的子類所訪問;基類的私有成員是不可見的,派生類不可訪問基類中的私有成員。
基類成員對派生類對象的可見性對派生類對象來說,基類的所有成員都是不可見的。所以,在私有繼承時(shí),基類的成員只能由直接派生類訪問,而無法再往下繼承。
簡單來說派生類可以訪問基類的public, protected成員,繼承過來之后變成自己私有的。 派生類的對象啥都不能訪問。
class A
{
private:
int m_data1;
void print1() { cout << "private print1" << endl; }
protected:
int m_data2;
void print2() { cout << "protected print2" << endl; }
public:
A(int x = 1, int y = 2, int z = 3) : m_data1(x), m_data2(y), m_data3(z) {}
int m_data3;
void print3() { cout << "protected print3" << endl; }
};
class B : private A
{
public:
void test_public() {
cout << m_data3 << endl;
print3();
}
void test_protected() {
cout << m_data2 << endl;
print2();
}
void test_private() {
// 下面兩行編譯不過,B類內(nèi)無法訪問父類的私有成員
// cout << m_data1 << endl;
// print1();
}
};
int main(int argc, char const* argv[])
{
B b;
b.test_public();
b.test_protected();
b.test_private();
// cout << b.m_data3 << endl; // // 編譯不過,子類對象無法訪問父類public的成員
// cout << b.m_data2 << endl; // 編譯不過,子類對象無法訪問父類protected的成員
// cout << b.m_data1 << endl; // 編譯不過,子類對象無法訪問父類private的成員
return 0;
}
protected 方式繼承
基類成員對派生類的可見性對派生類來說,基類的公有成員和保護(hù)成員是可見的,基類的公有成員和保護(hù)成員都作為派生類的保護(hù)成員,并且不能被這個派生類的子類的對象所訪問,但可以被派生類的子類所訪問;基類的私有成員是不可見的,派生類不可訪問基類中的私有成員。
基類成員對派生類對象的可見性對派生類對象來說,基類的所有成員都是不可見的。
簡單來說: 派生類可以訪問基類的public, protected,繼承過來都變成了protected,派生類對象啥都不能訪問。
總結(jié)
對于這三種方式繼承的派生類來說: 都能訪問基類的public, protected 成員;
- public 的方式繼承到派生類,這些成員的權(quán)限和在基類里的權(quán)限保持一致;
- protected方式繼承到派生類,成員的權(quán)限都變?yōu)閜rotected;
- private 方式繼承到派生類,成員的權(quán)限都變?yōu)閜rivate;
對于三種方式派生類的對象來說: 只有public的方式繼承后,派生來的對象只能訪問基類的public成員,protected和private方式繼承,派生類的對象都不可以訪問父類的成員。
例: 請考慮標(biāo)記為A到J的語句在編譯時(shí)可能出現(xiàn)的情況。
#include<iostream>
#include<cstdio>
class Parent
{
public:
Parent(int var=-1) {
m_nPub = var;
m_nPtd = var;
m_bPrt = var;
}
int m_nPub;
protected:
int m_nPtd;
private:
int m_nPrt;
};
class Child1 : public Parent
{
public:
int GetPub() { return m_nPub; }
int GetPtd() { return m_nPtd; }
int GetPrt() { return m_nPrt; }
// A
};
class Child2 : protected Parent
{
public:
int GetPub() { return m_nPub; }
int GetPtd() { return m_nPtd; }
int GetPrt() { return m_nPrt; }
// B
};
class Child3 : private Parent
{
public:
int GetPub() { return m_nPub; }
int GetPtd() { return m_nPtd; }
int GetPrt() { return m_nPrt; }
// C
};
int main(int argc, char const *argv[])
{
Child1 cd1;
Child2 cd2;
Child3 cd3;
int nVar = 0;
// public inherited
cd1.m_nPub = nVar; // D
cd1.m_nPtd = nVar; // E
nVar = cd1.GetPtd(); // F
// protected inherited
cd2.m_nPub = nVar; // G
nVar = cd2.GetPtd(); // H
// private inherited
cd3.m_nPub = nVar; // I
nVar = cd3.GetPtd(); // J
return 0;
}
A, B, C都錯誤,因?yàn)?m_nPrt 是父類的private變量,子類不能訪問。
D正確。 cdl是公有繼承,可以訪問并改變父類的公有變量。
E 錯誤。 m_nPtd 是父類 Parent 的保護(hù)變量,不可以被公有繼承的 cdl 訪問, 更不可以被修改。 雖然 m_nPtd 是父類 Parent 的保護(hù)變量,經(jīng)過公有繼承后, m_nPtd 在子類中依然是protected, 而子類的對象cdl是不能訪問自身的protected成員,只能訪問public成員。
F正確。派生類內(nèi)可以訪問父類的保護(hù)變量。
G錯誤。cd2是保護(hù)繼承的,派生類對象不能訪問父類成員。
H正確。派生類內(nèi)可以訪問父類的保護(hù)變量。
I錯誤。cd2是私有繼承的,派生類對象不能訪問父類成員。
J正確。派生類內(nèi)可以訪問父類的保護(hù)變量。
以上就是詳解C++ 中的三種繼承方式的詳細(xì)內(nèi)容,更多關(guān)于c++ 繼承方式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c++ 結(jié)構(gòu)體內(nèi)存對齊基本概念及示例
這篇文章主要介紹了c++ 結(jié)構(gòu)體內(nèi)存對齊基本概念及示例,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下2020-12-12
VC下通過系統(tǒng)快照實(shí)現(xiàn)進(jìn)程管理的方法
這篇文章主要介紹了VC下通過系統(tǒng)快照實(shí)現(xiàn)進(jìn)程管理的方法,較為詳細(xì)的講述了VC下通過系統(tǒng)快照實(shí)現(xiàn)進(jìn)程管理的原理與具體實(shí)現(xiàn)方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10
C++數(shù)據(jù)結(jié)構(gòu)之單鏈表
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個個結(jié)點(diǎn)鏈結(jié)成的。結(jié)點(diǎn)包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來存儲數(shù)據(jù)元素的信息,指針域用來存儲下一個結(jié)點(diǎn)的地址,更詳細(xì)內(nèi)容請需要的小伙伴參考下面文章內(nèi)容2022-01-01
C++深入分析內(nèi)聯(lián)函數(shù)的使用
為了消除函數(shù)調(diào)用的時(shí)空開銷,C++ 提供一種提高效率的方法,即在編譯時(shí)將函數(shù)調(diào)用處用函數(shù)體替換,類似于C語言中的宏展開。這種在函數(shù)調(diào)用處直接嵌入函數(shù)體的函數(shù)稱為內(nèi)聯(lián)函數(shù)(Inline Function),又稱內(nèi)嵌函數(shù)或者內(nèi)置函數(shù)2022-04-04
C++實(shí)現(xiàn)LeetCode(40.組合之和之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(40.組合之和之二),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

