C++ protected(受保護的)詳解

2020-07-16 10:04:19
在《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 行都會編譯出錯,因為在類的成員函數外部,不能存取物件的私有成員和保護成員。

在基礎類別中,一般都將需要隱藏的成員說明為保護成員而非私有成員。