C++中類繼承public,protected和private關鍵字作用詳解及派生類的訪問許可權

Luyao發表於2020-07-13

注意:本文有時候會用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優先順序最高,相當於覆蓋了其它兩個優先順序)。

相關文章