C++的三種繼承方式:public,protected,private


C++訪問權限控制符 :

        public 公有成員 基類、派生類、友元、外部都可以訪問

        protected 保護成員 基類、派生類、友元可以訪問

        private 私有成員 基類、友元可以訪問

同樣的C++繼承方式有public,protected,private三種:


 

今天就來給大家簡單介紹一下C++的三種繼承方式。


 

1、public 方式繼承

基類成員對派生類的可見性對 派生類 來說,基類的公有成員和保護成員可見,基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀態;基類的私有成員不可見,基類的私有成員仍然是私有的,派生類不可訪問基類中的私有成員。

基類成員對派生類對象的可見性對 派生類對象 來說,基類的公有成員是可見的,其他成員是不可見的。

所以,在公有繼承時,派生類的對象可以訪問基類中的公有成員,派生類的成員函數可以訪問基類中的公有成員和保護成員。

簡單來說,派生類能訪問基類的public, protected成員,繼承過來權限不變,派生類對象只能訪問基類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類內無法訪問父類的私有成員

        // 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;

}


 

2、private 方式繼承

基類成員對其對象的可見性與一般類及其對象的可見性相同,公有成員可見,其他成員不可見

基類成員對派生類的可見性對 派生類 來說,基類的公有成員和保護成員是可見的,基類的公有成員和保護成員都作為派生類的私有成員,並且不能被這個派生類的子類所訪問;基類的私有成員是不可見的,派生類不可訪問基類中的私有成員。

基類成員對派生類對象的可見性對 派生類對象 來說,基類的所有成員都是不可見的。所以,在私有繼承時,基類的成員只能由直接派生類訪問,而無法再往下繼承。

簡單來說派生類可以訪問基類的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類內無法訪問父類的私有成員

        // 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;

 


 

3、protected 方式繼承

基類成員對派生類的可見性對 派生類 來說,基類的公有成員和保護成員是可見的,基類的公有成員和保護成員都作為派生類的保護成員,並且不能被這個派生類的子類的對象所訪問,但可以被派生類的子類所訪問;基類的私有成員是不可見的,派生類不可訪問基類中的私有成員。

基類成員對派生類對象的可見性對派生類對象來說,基類的所有成員都是不可見的。

簡單來說: 派生類可以訪問基類的public, protected,繼承過來都變成了protected,派生類對象啥都不能訪問。

總結

對於這三種方式繼承的 派生類 來說: 都能訪問基類的public, protected 成員;

public 的方式繼承到派生類,這些成員的權限和在基類里的權限保持一致;

protected方式繼承到派生類,成員的權限都變為protected;

private 方式繼承到派生類,成員的權限都變為private;

對於三種方式 派生類的對象 來說: 只有public的方式繼承后,派生來的對象只能訪問基類的public成員,protected和private方式繼承,派生類的對象都不可以訪問父類的成員。

例: 請考慮標記為A到J的語句在編譯時可能出現的情況。

#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都錯誤,因為 m_nPrt 是父類的private變量,子類不能訪問。

D正確。 cdl是公有繼承,可以訪問並改變父類的公有變量。

E 錯誤。 m_nPtd 是父類 Parent 的保護變量,不可以被公有繼承的 cdl 訪問, 更不可以被修改。 雖然 m_nPtd 是父類 Parent 的保護變量,經過公有繼承后, m_nPtd 在子類中依然是protected, 而子類的對象cdl是不能訪問自身的protected成員,只能訪問public成員。

F正確。派生類內可以訪問父類的保護變量。

G錯誤。cd2是保護繼承的,派生類對象不能訪問父類成員。

H正確。派生類內可以訪問父類的保護變量。

I錯誤。cd2是私有繼承的,派生類對象不能訪問父類成員。

J正確。派生類內可以訪問父類的保護變量。

文章來源:https://segmentfault.com/a/1190000039299077?utm_source=tuicool&utm_medium=referral

最后,特別推薦一個分享C/C++和算法的優質內容,學習交流,技術探討,面試指導,簡歷修改...還有超多源碼素材等學習資料,零基礎的視頻等着你!

還沒關注的小伙伴,可以長按關注一下:


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM