Защищенные члены
Дадим пример защищенных членов, вернувшись к классу window из предыдущего раздела. Здесь функции _draw() предназначались только для использования в производных классах, поскольку предоставляли неполный набор возможностей, а поэтому не были достаточны удобны и надежны для общего применения. Они были как бы строительным материалом для более развитых функций. С другой стороны, функции draw() предназначались для общего применения. Это различие можно выразить, разбив интерфейсы классов window на две части - защищенный интерфейс и общий интерфейс:
class window {
public:
virtual void draw();
// ...
protected:
void _draw();
// другие функции, служащие строительным материалом
private:
// представление класса
};
Такое разбиение можно проводить и в производных классах, таких, как window_w_border или window_w_menu.
Префикс _ используется в именах защищенных функций, являющихся частью реализации класса, по общему правилу: имена, начинающиеся с _, не должны присутствовать в частях программы, открытых для общего использования. Имен, начинающихся с двойного символа подчеркивания, лучше вообще избегать (даже для членов).
Вот менее практичный, но более подробный пример:
class X {
// по умолчанию частная часть класса
int priv;
protected:
int prot;
public:
int publ;
void m();
};
Для члена X::m доступ к членам класса неограничен:
void X::m()
{
priv = 1; // нормально
prot = 2; // нормально
publ = 3; // нормально
}
Член производного класса имеет доступ только к общим и защищенным членам:
class Y : public X {
void mderived();
};
Y::mderived()
{
priv = 1; // ошибка: priv частный член
prot = 2; // нормально: prot защищенный член, а
// mderived() член производного класса Y
publ = 3; // нормально: publ общий член
}
В глобальной функции доступны только общие члены:
void f(Y* p)
{
p->priv = 1; // ошибка: priv частный член
p->prot = 2; // ошибка: prot защищенный член, а f()
// не друг или член классов X и Y
p->publ = 3; // нормально: publ общий член
}