C++的關鍵字public,private和protected

先寫最基礎的吧。C進入C++最先碰到的就是class,跟structure很像,但是一開始就多了幾個關鍵字public,private和protected。下面就我目前自己的理解來說一說。
這幾個關鍵都是修飾class內部成員的訪問權限,簡單的理解就是:

  • 這些都是我的東西,你想要的話,是可以直接拿呢;還是需要我給你一把鑰匙先?
  • 能直接拿的,那就是public成員。
  • 需要鑰匙的,那就是private或者protected成員。

不過實際用起來,我理解可以分成兩種case:

1. 聲明class時,修飾內部成員屬性

看一段code:

#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
    int a;
    A() {
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    }
    void fun() {
        cout << a << endl;        //  在類內部訪問,正確
        cout << a1 << endl;       //  內部訪問,正確
        cout << a2 << endl;       //  內部訪問,正確
        cout << a3 << endl;       //  內部訪問,正確
    }
public:
    int a1;
protected:
    int a2;
private:
    int a3;
};
int main() {
    A itema;
    itema.a = 10;       // 在類外部訪問public成員a,正確
    itema.a1 = 20;      // 在類外部訪問public成員a1,正確
    itema.a2 = 30;      // 在類外部訪問protected成員a2,錯誤,類外不能訪問protected成員
    itema.a3 = 40;      // 在類外部訪問private成員a3,錯誤,類外不能訪問private成員
    system("pause");
    return 0;
}

由註釋可以看到,通過不同的關鍵字修飾的類成員,其訪問權限就有了區別。

小結一下:

  • public成員可以在類外部被訪問。
  • private成員只屬於類自己,外部想訪問private成員,只能通過類方法。
  • protected成員目前的訪問屬性與private成員一樣

2. 類繼承時,使基類成員屬性在派生類中發生變化

類如果不發生派生,好像就看不出protected和private的區別的,別慌,繼續往下走。
因爲是3個關鍵字,所以就有了3種繼承方式:

2.1 public繼承

剛開始,我是我爸爸生的,我想各方面都跟我爹保持一致,我不想對父類的各個成員屬性作任何改變,那麼,我就用public繼承。
還是看code和註釋一目瞭然:

#include<iostream>
#include<assert.h>
using namespace std;
 
class A {
public:
    int a;
    A() {
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    }
    void fun() {
          cout << a << endl;    // 訪問public成員a,正確
          cout << a1 << endl;   // 訪問public成員a1,正確
          cout << a2 << endl;   // 類成員函數訪問protected成員a2,正確
          cout << a3 << endl;   // 類成員函數訪問private成員a3,正確
    }
public:
      int a1;
protected:
      int a2;
private:
      int a3;
};

// 類B public繼承 類A,所以,B繼承了A的成員a1,a2,屬性也完全一樣(注:B無法繼承A的private成員a3)
class B : public A {                 
public:
      int a;
      B(int i) {
          A();
          a = i;
      }
      void fun() {
          cout << a << endl;        // 正確,訪問自己的public成員
          cout << a1 << endl;       // 正確,基類的public成員,在派生類中仍是public成員。
          cout << a2 << endl;       // 正確,基類的protected成員,在派生類中仍是protected,並且可以被派生類訪問。
          cout << a3 << endl;       // 錯誤,基類的private成員不能被派生類訪問。(private成員只能由本類的成員訪問)
      }
};

int main() {
    B b(10);
    cout << b.a << endl;
    cout << b.a1 << endl;   // 正確,類外可以訪問b的public成員a1
    cout << b.a2 << endl;   // 錯誤,類外不能訪問protected成員a2
    cout << b.a3 << endl;   // 錯誤,類外不能訪問private成員
    system("pause");
    return 0;
}

小結一下:

  • public繼承出來的派生類,基類的成員屬性在派生類中不會發生任何變化。
  • 派生類無法訪問基類的private成員。(我理解爲:派生類無法繼承基類的private成員,因此派生類就沒有這個成員,自然也就無法訪問)
  • 派生類可以繼承基類的protected成員,並且在派生類中,仍然是protected屬性。

2.2 protected繼承

OK,龍生九子,總有熊孩子。雖然我是我爸爸生出來的,但我爸當年讓你直接隨便拿的一些東西(蒼老師教學片),在我這兒,我不想讓你直接取了(我要私藏起來,鎖抽屜裏,隱私,懂不懂!?),我想變一下,那咋辦?
那好辦,C++就是這點好,你想要的,它都能給你 : )
那我們就不public繼承了嘛,關鍵字不是還有2個嗎,protected也可以用?
那當然了,請看code:

#include<iostream>
#include<assert.h>
using namespace std;
class A {
public:
    int a;
    A() {
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    }
    void fun() {
        cout << a << endl;    // 正確,自己的方法訪問自己的成員
        cout << a1 << endl;   //正確
        cout << a2 << endl;   //正確
        cout << a3 << endl;   //正確
    }
public:
    int a1;
protected:
    int a2;
private:
    int a3;
};

// B protected繼承 A,那麼A的public成員,在B中就“降級”變成protected,protected和private成員屬性不變
class B : protected A {
public:
    int a;
    B(int i) {
        A();
        a = i;
    }
    void fun() {
        cout << a << endl;       //正確,B自己的public成員。
        cout << a1 << endl;       //正確,基類的public成員,在派生類中變成了protected,可以被派生類訪問。
        cout << a2 << endl;       //正確,基類的protected成員,在派生類中還是protected,可以被派生類訪問。
        cout << a3 << endl;       //錯誤,基類的private成員不能被派生類訪問。
    }
};

int main() {
    B b(10);
    cout << b.a << endl;       //正確,對象b自己的的public成員a
    cout << b.a1 << endl;      //錯誤,b.a1這時候是protected屬性,protected成員不能在類外訪問。
    cout << b.a2 << endl;      //錯誤,protected成員不能在類外訪問。
    cout << b.a3 << endl;      //錯誤,private成員不能在類外訪問。
    system("pause");
    return 0;
}

你看,這樣,爸爸的public片片,在兒子這裏,就鎖起來了吧!
小結一下

  • protected繼承出的派生類,基類的成員屬性在派生類中會發生改變。
  • 基類的public成員,在派生類中被“降級”成protected。
  • 基類的protected成員,在派生類中仍然是protected。
  • 基類的private成員,派生類依然無法訪問。

2.3 private繼承

來到最後一個關鍵字private。
沒有最熊,只有更熊的娃。我爸讓你能直接看的所有東西,現在到我這兒,對不起,我都不想再讓你直接看了;並且,我還不想給我的兒子繼承了!(蒼老師只屬於我,自己親兒子也別想!)
那要達到這樣的效果,就需要private繼承了。
看code:

#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
    int a;
    A() {
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    }
    void fun() {
        cout << a << endl;    //正確
        cout << a1 << endl;   //正確
        cout << a2 << endl;   //正確
        cout << a3 << endl;   //正確
    }
public:
    int a1;
protected:
    int a2;
private:
    int a3;
};

// B private繼承 A,那麼在B裏,A的public和protected成員都變成了B的private成員
class B : private A {
public:
    int a;
    B(int i) {
        A();
        a = i;
    }
    void fun() {
        cout << a << endl;       //正確,內部訪問public成員a。
        cout << a1 << endl;       //正確,基類public成員,在派生類中變成了private,可以被派生類訪問。
        cout << a2 << endl;       //正確,基類的protected成員,在派生類中變成了private,可以被派生類訪問。
        cout << a3 << endl;       //錯誤,基類的private成員不能被派生類訪問。
    }
};

int main(){
  B b(10);
  cout << b.a << endl;       //正確。b.a是b的public成員
  cout << b.a1 << endl;      //錯誤,private成員不能在類外訪問。
  cout << b.a2 << endl;      //錯誤, private成員不能在類外訪問。
  cout << b.a3 << endl;      //錯誤,private成員不能在類外訪問。
  system("pause");
  return 0;
}

再次小結一下

  • private繼承後,基類的public和protected成員,在派生類裏都被“降級”成private。
  • 訪問派生類的private成員,自然遵循private規則。
  • 如果有派生類再派生“孫子”類,那麼這個“孫子”類將無法訪問“爺爺”類和“父親”類中的任何private成員。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章