首頁 > 軟體

C++非繼承時函數成員存取屬性和類繼承過程中的存取控制

2022-03-11 10:00:11

一、非繼承時public、protected和private成員的存取屬性

C++中保護成員使用protected進行宣告,那麼protected、public和private三者有什麼區別呢?

先說結論:非繼承時,protected成員和private成員沒有任何區別,都是類內部可以直接存取它們、類外部的類物件不可存取它們、類內部的類物件可以存取它們;相比之下,public成員在類內部、類外部的類物件、類內部的類物件中都是可直接存取的。

下面定 義的Bird類:

class Bird {
public:
    Bird() { 
        eat();   // 正確,類內可以存取保護成員
    };
protected:
    void eat() { printf("Bird eating n"); }
};

上述程式碼錶明,類內是可以直接存取protected成員的,下面來看類外部的類物件:

int main() {
    Bird bird();
    bird.eat();  // 錯誤,protected成員類外部物件不可存取
}

上述程式碼錶明,類外部類物件是不能直接存取protected成員的。

所以說,非繼承時protected成員和private成員沒有差別。它們真正展示出差異是在“基礎類別和子類的繼承”時,具體分析留在後面紀錄檔。

重點:上述分析強調了“類外部的類物件和類內部的類物件”是不同的(類內部類物件是指:Bird類的複製建構函式就使用Bird類物件的參照可以存取其私有成員和保護成員)。因此,才要特殊指明“類外部的類物件不能存取protected和private成員,類內部的類物件可以存取其protected和private成員”。

二、C++類別繼承過程中存取控制

在子類繼承父類別的過程中,子類可以指定以何種方式繼承父類別:public繼承、protected繼承和private繼承,這個過程可以稱為“存取控制”。

在學習存取控制之前,需要知道類含有三種成員public成員、protected成員、private成員。在非繼承的情況下,這三種成員的存取屬性是不同的:public成員在類內部和外部均可被直接存取;protected和private成員均可以被類內部和類內部的類物件存取,均不能被類外部的類物件存取。為了便於自己記憶,稱這個規則為“非繼承時三種成員的存取法則”
此知識點的複雜性在於繼承方式有三種,每種繼承方式又對應三種成員,所以一共是九種情況。

為此,採用表格形式記錄如下:

上表中“子類吸收後”表示父類別成員在子類中是何種身份(身份指:publicprotectedprivate),也就是說不同的繼承型別使得父類別成員在子類中的身份不同。

比如:在protected繼承型別中,父類別中的public成員對應在子類中為protected成員,此時子類內部(指成員函數和子類物件)可以存取該protected成員,但是子類外部的子類物件無法存取該成員。也就是說,通過protected型別的繼承,該成員從父類別中的public成員變為子類中的protected成員。

下面是public繼承的例子,其中父類別為Animal,子類為Duck:

class Animal {
public:
    Animal(int age_) { age = age_; printf("Init Animal n"); 
    }

    void eat() { printf("Animal eating! n"); }
protected:
    void run() { printf("Animal Running! n"); }
private:
    int age=0;
    void showAge() { printf("Age is %d", age); }
};

父類別Animal中分別定義了public型別的eat()函數、protected型別的run()函數、private型別的showAge()函數。子類可以通過選擇不同的繼承方式,改變這幾個函數在子類中的存取屬性:

class Duck:public Animal {
public:
    Duck(int age_) :Animal(age_) { 
        printf("init Duck! n");
        run(); // 正確,子類內部可以存取基礎類別public成員
        eat(); // 正確,子類內部可以存取基礎類別protected成員
        showAge(); // 錯誤,子類內部不可存取基礎類別的private成員
    };
};

總結:

按照自己目前的理解,不管繼承方式為publicprotectedprivate三種中的哪一個,父類別的private成員對應到子類中均“不可直接存取”。此外,子類不繼承父類別的建構函式和解構函式。

疑惑:

書中所說的“不可直接存取”,目前自己並不知道如何間接存取,猜測可能是採用 “get” 和 “set” 方式進行間接存取。

到此這篇關於C++非繼承時函數成員存取屬性和類繼承過程中的存取控制的文章就介紹到這了,更多相關C++非繼承和類繼承存取內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com