本文的前提是使用public继承。
protected是修饰类成员的一个关键字。其作用是使protected类成员不能够从类外部访问,在基类中,其与private的成员可看作具有相同的访问限制,即只能被该基类的成员函数访问。而protected成员还有一个特点就是,通过public继承得到的子类,其成员函数能够直接访问基类的protected成员,与此不同的是,子类需要通过继承得来的public成员函数来访问父类的private成员,而不能直接访问。
来看个例子:
class Father
{
private:
int age;
protected:
string name;
public:
Father();
Father(const string & n, int a);
};
Father::Father()
{
age = 0;
name = "none";
}
Father::Father(const string & n, int a)
{
name = n;
age = a;
}
class Son : public Father
{
private:
string hobby;
public:
Son();
Son(const string & h, const string & n, int);
};
Son::Son()
{
hobby = "none";
name = "none"; // 直接访问
}
Son::Son(const string & h, const string & n, int a) : Father(n, a) // 调用父类构造函数
{
hobby = h;
}
上面的代码能够通过编译,说明name能够被子类直接访问(Son类的默认构造函数直接访问),也能够被间接访问(Son类的第二个构造函数通过调用父类构造函数访问)。
下面来测试不允许的访问(只有一种):
不允许从外部访问:
int main()
{
Father * f = new Father("Tom", 45);
Son * s = new Son("Wathing movies", "Petter", 18);
// 从外部访问protected成员
f->name = "Washington";
s->name = "Richard";
return 0;
}
编译错误信息:
综上,protected成员在public继承中的访问限制是很明显的:能被基类和子类直接访问,但不能被外界直接访问。
但是,不推荐使用protected,而推荐使用private,这样能够保证基类的成员及其一系列运作机制不被子类打乱,能够使bug出现的几率更少。然而使用protected能够使子类直接访问父类的protected成员,使得对一些项的修改和调用一些父类的函数更加方便。