在《C++類別成員的存取範圍》一節中介紹過類的成員可以是私有成員(private)和公有成員(public)。實際上,類的成員還可以用 protected 存取範圍說明符修飾,從而成為“保護成員”。
保護成員的可存取範圍比私有成員大,比公有成員小。能存取私有成員的地方都能存取保護成員。
保護成員擴大的存取範圍表現在:基礎類別的保護成員可以在派生類的成員函數中被存取。
引入保護成員的理由是:基礎類別的成員本來就是派生類的成員,因此對於那些出於隱藏的目的不宜設為公有,但又確實需要在派生類的成員函數中經常存取的基礎類別成員,將它們設定為保護成員,既能起到隱藏的目的,又避免了派生類成員函數要存取它們時只能間接存取所帶來的麻煩。
不過需要注意的是,派生類的成員函數只能存取所作用的那個物件(即this指標指向的物件)的基礎類別保護成員,不能存取其他基礎類別物件的基礎類別保護成員。來看下面的例子:
class CBase {
private: int nPrivate; //私有成員
public: int nPublic; //公有成員
protected: int nProtected; // 保護成員
};
class CDerived :public CBase
{
void AccessBase ()
{
nPublic = 1; // OK
nPrivate = 1; // 錯,不能存取基礎類別私有成員
nProtected = 1; // OK,存取從基礎類別繼承的protected成員
CBase f;
f.nProtected = 1; //錯,f不是函數所作用的物件
}
};
int main()
{
CBase b;
CDerived d;
int n = b.nProtected ; //錯,不在派生類成員函數內,不能存取基礎類別保護成員
n = d.nPrivate; //錯,此處不能存取d的私有成員
int m = d.nPublic; //OK
return 0;
}
第 11 行編譯出錯,因為在派生類的成員函數中不能存取基礎類別的私有成員。
第 12 行沒有問題,在派生類的成員函數中可以存取基礎類別的保護成員。
第 14 行編譯出錯,因為 f 不是 this 指標所指向的物件,即不是 AccessBase 函數所作用的 物件,所以不能存取其保護成員。
第 21 行和第 22 行都會編譯出錯,因為在類的成員函數外部,不能存取物件的私有成員和保護成員。
在基礎類別中,一般都將需要隱藏的成員說明為保護成員而非私有成員。