先寫最基礎的吧。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成員。