Эти три ключевых слова также используются в совершенно ином контексте для указания модели наследования видимости .
В этой таблице собраны все возможные комбинации объявления компонента и модели наследования, представляющие результирующий доступ к компонентам, когда подкласс полностью определен.
Таблица выше интерпретируется следующим образом (взгляните на первый ряд):
, если компонент объявлен как public , а его класс унаследован как public результирующий доступ is public .
Пример:
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
Полученный доступ к переменным p
, q
, r
в классе Subsub равен none .
Другой пример:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
Полученный доступ для переменных y
, z
в классе Sub защищен , а для переменной x
равен нет .
Более подробный пример:
class Super {
private:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
int main(void) {
Super object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Теперь давайте определим подкласс:
class Sub : Super { };
int main(void) {
Sub object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Определенный класс с именем Sub, который является подклассом класса с именем Super
или класс Sub
является производным от класса Super
.
Класс Sub
не содержит ни новых переменных, ни новых функций. Означает ли это, что любой объект класса Sub
наследует все признаки после того, как класс Super
фактически является копией объектов класса Super
?
Нет . Это не так.
Если мы скомпилируем следующий код, мы получим только ошибки компиляции, говорящие о том, что методы put
и get
недоступны. Зачем?
Когда мы опускаем спецификатор видимости, компилятор предполагает, что мы собираемся применить так называемое личное наследование . Это означает, что все публичные компоненты суперкласса превращаются в частный доступ, частные компоненты суперкласса вообще не будут доступны. Следовательно, это означает, что вам не разрешено использовать последний внутри подкласса.
Мы должны сообщить компилятору, что мы хотим сохранить ранее использованную политику доступа.
class Sub : public Super { };
Не вводите в заблуждение : это не означает, что частные компоненты Супер
класс (например, переменная хранения) станет общедоступным в
несколько волшебным образом. Приватные компоненты останутся Приватными , Публичными
останется публичным .
Объекты класса Sub
могут делать "почти" то же самое, что и их старшие братья и сестры, созданные из класса Super
. "Практически" , поскольку тот факт, что он является подклассом, также означает, что класс потерял доступ к закрытым компонентам суперкласса . Мы не можем написать функцию-член класса Sub
, которая могла бы напрямую манипулировать переменной хранения.
Это очень серьезное ограничение. Есть ли обходной путь?
Да .
Третий уровень доступа называется защищен . Ключевое слово protected означает, что помеченный компонент ведет себя как общедоступный, когда используется любым из подклассов, и похож на частный для остального мира . - Это верно только для публично унаследованных классов (например, суперкласса в нашем примере) -
class Super {
protected:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
class Sub : public Super {
public:
void print(void) {cout << "storage = " << storage;}
};
int main(void) {
Sub object;
object.put(100);
object.put(object.get() + 1);
object.print();
return 0;
}
Как вы видите в примере кода, мы добавили в класс Sub
новую функциональность, и она делает одну важную вещь: она обращается к переменной хранения из суперкласса .
Это было бы невозможно, если бы переменная была объявлена как приватная.
В области видимости основной функции переменная все равно остается скрытой, поэтому, если вы напишите что-то вроде:
object.storage = 0;
Компилятор сообщит вам, что это error: 'int Super::storage' is protected
.
Наконец, последняя программа выдаст следующий вывод:
storage = 101