// Эта программа не скомпилируется.
#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 можно использовать не только для придания членам класса статуса "защищенности", но и для наследования базового класса. Если базовый класс наследуется как защищенный, все его открытые и закрытые члены становятся защищенными членами производного класса. Рассмотрим пример.
// Демонстрация наследования защищенного базового класса.
#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; }
};