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

};

// Члены i и j наследуются косвенно через класс derived1.

class derived2 : public derived1 {

  int m;

 public :

  void setm() { m = i-j; } // правомерный доступ

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

};

int main()

{

 derived1 ob1;

 derived2 ob2;

 ob1.set (2, 3);

 ob1.show();

 ob1.setk();

 ob1.showk();

 ob2.set (3, 4);

 ob2.show();

 ob2.setk();

 ob2.setm();

 ob2.showk();

 ob2.showm();

 return 0;

}

Если базовый класс наследуется закрытым способом (т.е. с использованием спецификатора private), защищенные (derived) члены этого базового класса становятся закрытыми (private) членами производного класса. Следовательно, если бы в предыдущем примере класс base наследовался закрытым способом, то все его члены стали бы private-членами класса derived1, и в этом случае они не были бы доступны для класса derived2. (Однако члены i и j по-прежнему остаются доступными для класса derived1.) Эта ситуация иллюстрируется в следующей программе, которая поэтому некорректна (и не скомпилируется). Все ошибки отмечены в комментариях.

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

#include

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 для наследования базового класса
Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги