Язык программирования C++ от Страуструпа

Защищенные члены


Дадим пример защищенных членов, вернувшись к классу 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 общий член

}



Содержание раздела