C++ protected(受保护的)详解

在《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 行都会编译出错,因为在类的成员函数外部,不能访问对象的私有成员和保护成员。

在基类中,一般都将需要隐藏的成员说明为保护成员而非私有成员。