Выбрать главу

// Эта программа не скомпилируется.

#include <iostream>

using namespace std;

class base {

 protected:

  int i, j;

 public:

  void set (int a, int b) { i = a; j = b; }

  void show() { cout << i << " " << j << "\n"; }

};

// Теперь все элементы класса base будут закрыты

// в рамках класса derived1.

class derived1 : private base {

  int k;

 public:

  // Вызовы этих функций вполне законны, поскольку

  // переменные i и j являются одновременно

  // private-членами класса derived1.

  void setk() { k = i*j; } // OK

  void showk() { cout << k << "\n"; }

};

// Доступ к членам i, j, set() и show() не наследуется.

class derived2 : public derived1 {

  int m;

 public :

  // Неверно, поскольку члены i и j закрыты в рамках

  // класса derived1.

  void setm() { m = i-j; } // ошибка

  void showm() { cout << m << "\n"; }

};

int main()

{

 derived1 ob1;

 derived2 ob2;

 ob1.set(1, 2); // Ошибка: нельзя вызывать функцию set().

 ob1.show(); // Ошибка: нельзя вызывать функцию show().

 ob2.set(3, 4); // Ошибка: нельзя вызывать функцию set().

 ob2.show(); // Ошибка: нельзя вызывать функцию show().

 return 0;

}

Несмотря на то что класс base наследуется классом derived1 закрытым способом, класс derived1, тем не менее, имеет доступ к public- и protected-членам класса base. Однако он не может эту привилегию передать дальше, т.е. вниз по иерархии классов. Ключевое слово protected— это часть языка C++. Оно обеспечивает механизм защиты определенных элементов класса от модификации функциями, которые не являются членами этого класса, но позволяет передавать их "по наследству".

Спецификатор protected можно также использовать в отношении структур. Но его нельзя применять к объединениям, поскольку объединение не наследуется другим классом. (Некоторые компиляторы допускают использование спецификатора protected в объявлении объединения, но, поскольку объединения не могут участвовать в наследовании, в этом контексте ключевое слово protected будет равносильным ключевому слову private.)

Спецификатор защищенного доступа может стоять в любом месте объявления класса, но, как правило, protected-члены объявляются после (объявляемых по умолчанию) private-членов и перед public-членами. Таким образом, самый общий формат объявления класса обычно выглядит так.

class имя_класса {

  private-члены

 protected:

  protected-члены

 public:

  public-члены

};

Напомню, что раздел защищенных членов необязателен.

Использование спецификатора protected для наследования базового класса

Спецификатор protected можно использовать не только для придания членам класса статуса "защищенности", но и для наследования базового класса. Если базовый класс наследуется как защищенный, все его открытые и закрытые члены становятся защищенными членами производного класса. Рассмотрим пример.

// Демонстрация наследования защищенного базового класса.

#include <iostream>

using namespace std;

class base {

  int i;

 protected:

  int j;

 public:

  int k;

  void seti(int a) { i = a; }

  int geti() { return i; }

};