1) 前言
在我學習C++的過程中,類中成員的權限控制一直是比較頭疼的一個點,一會public,一會又private,還有protected,再加點繼承,而且又有公有繼承、私有繼承,保護繼承,所以感覺會比較亂。
后來不斷學習過程中,慢慢理順了它們的關系,稍微分類總結一下,在這個問題上基本上就沒再栽過跟頭。如有筆誤,希望大神指點一下!
2 )C++的水平權限控制
首先解釋幾個特定詞,下面要用到:
水平權限:在一個類中,成員的權限控制,就是類中的成員函數能否訪問其他成員、類的對象能否訪問類中某成員。
垂直權限:在派生類中,對從基類繼承來的成員的訪問。
內部訪問:類中成員函數對其他成員的訪問。
外部訪問:通過類的對象,訪問類的成員函數或者成員變量,有的書里也稱之為對象訪問。
這里的“水平”是自己為了容易理解而用的,其實也可以用“橫向”這類的詞,其他的詞類似;詞的叫法意義不大,但對加深理解卻可以事半功倍!
當private,public,protected單純的作為一個類中的成員(變量和函數)權限設置時:
類的成員函數以及友元函數可以訪問類中所有成員,但是在類外通過類的對象,就只能訪問該類的共有成員。
注:友元函數包括兩種:設為友元的全局函數,設為友元類中的成員函數;這里將友元函數看成內部函數,方便記憶!
總結為下表:
類中屬性 |
private |
protected |
public |
內部可見性 |
可見 |
可見 |
可見 |
外部可見性 |
不可見 |
不可見 |
可見 |
程序驗證如下:這里沒有friend的成員,另外成員變量和成員函數的權限控制是一樣的。
1 #include <iostream> 2 3 class Foo 4 { 5 public: 6 int a; 7 void public_fun(); 8 protected: 9 char b; 10 void protected_fun(); 11 private: 12 bool c; 13 void private_fun(); 14 }; 15 16 //驗證public成員內部可見性 17 void Foo::public_fun() 18 { 19 a = 10; 20 b = 'c'; 21 c = true; 22 } 23 24 //驗證protected成員函數的內部可見性 25 void Foo::protected_fun() 26 { 27 a = 10; 28 b = 'c'; 29 c = true; 30 } 31 32 //驗證private成員函數的內部可見性 33 void Foo::private_fun() 34 { 35 a = 10; 36 b = 'c'; 37 c = true; 38 } 39 40 int main() 41 { 42 Foo foo; 43 foo.public_fun();//驗證public成員外部可見性 44 foo.protected_fun();//驗證protected成員外部可見性,這里提示錯誤 45 foo.private_fun();//驗證private成員外部可見性,這里提示錯誤 46 return 0; 47 }
3)C++的垂直訪問控制
當private,public,protected作為繼承方式時:
派生類可以繼承基類中除了構造函數與析構函數(凡是與具體對象的類別息息相關的都不能被繼承,賦值運算符重載函數也不能被繼承)之外的成員,但是這些成員的訪問屬性在派生過程中是可以調整的。從基類繼承來的成員在派生類中的訪問屬性是由繼承方式控制的。
基類中屬性 |
private |
protected |
public |
private |
protected |
public |
private |
protected |
public |
繼承方式 |
private |
protected |
public |
||||||
內部可見性 |
不可見 |
private |
private |
不可見 |
protected |
protected |
不可見 |
protected |
public |
外部可見性 |
不可見 |
不可見 |
不可見 |
不可見 |
不可見 |
不可見 |
不可見 |
不可見 |
可見 |
派生類對基類成員的訪問形式主要有以下兩種:
(1)內部訪問:由派生類中新增的成員函數對基類繼承來的成員的訪問。
(2)外部訪問:在派生類外部,通過派生類的對象對從基類繼承來的成員的訪問。
4) 有關權限控制的理解
C++的權限控制,給人感覺有點繁瑣,特別是三種權限,再加上三種繼承方式,還有友元那些東西,非常讓人頭大,這里總結一下,基本上把最常見和常用的給理清楚啦,一些這方面的問題,比如實際工作或者筆試題目,即可迎刃而解。