Наследование классов в C++: что это и как он работает

Всем привет! Продолжаем изучать классы в C++. Сейчас поговорим об одном из свойств объектно ориентированного программирования - наследование.
Что такое наследование
Это принцип создание класса на базе уже существующе го, при этом у нас есть возможность пользоваться функционалом (свойствами и методами) базового. Классы созданные таким образом называются производными или дочерними, а на базе которого создаются - родителем или базовым.
Этот механизм в объектно ориентированном программировании очень сильная фича. Она в несколько раз экономит время на создание проекта, а также не нагружает его повторяющимся кодом.
Производный класс мы можем усовершенствовать, добавляя:
- Новые переменные.
- Функции.
- Конструкторы.
И все это не изменяя базовый класс.

Например, на базе класса про животного можно создать потомка про собаку.
Модификатор доступа protected
Для начала нужно знать об доступе protected, который является неотъемлемой частью наследования. protected - это модификатор доступа, который работает как private, но распространяется также на свойства предка. На рисунки ниже можно увидеть какими доступами можно пользоваться.

class Animals {
protected:
int zebras;
};
class Dog : public Animals {
int counter_zebras () {
return zebras;
}
};
Если бы переменная zebras
находилась в доступе private, то использование ее в функции counter_zebras
привило бы к ошибке.
Как создать дочерний класс
Чтобы наследовать класс нужно использовать конструкцию ниже:
class <имя потомка> : <модификатор наследования> <имя родительского класса>{};
Первое на что надо обратить внимание это на двоеточие (:
) оно одинарное, а не двойное как у области видимости.
Второе это <модификатор наследование>. При его оперировании можно задать какими модификаторами доступа родительского класса можно будет пользоваться в дочернем. Давайте поподробнее это разберем.
Вообщем можно указывать: public, private, protected. Из этих трех почти всегда используется public, но не плохо знать как работают другие.
Если вы новичок, то можете после информации про public перейти дальше.
public - использовать можно public
и protected
родительского класса. Кстати на рисунке выше изображены модификаторы доступа при использовании public.
class Animals {
public:
int counter; // общее кол животных
protected:
int zebras;
int bears;
int dogs;
// функция вычисление общего количества животных
count_animals() {
counter = dogs + bears + zebras;
}
set_dogs(int count_of_dogs) {
dogs = count_of_dogs;
}
};
class Dog : public Animals {
public:
int count_dogs() {
return dogs; // использовали переменную dog
}
};
- В строке 20: объявили функцию
public: count_dogs()
, которая возвращает переменнуюprivate: dogs
изanimals
.
private - пользоваться можно лишь свойствами (не функциями) родителя. Чтобы использовать функции нужно разрешить это напрямую (и без круглых скобок, только имя), а также разрешать нужно в публичном доступе (public). Делается это так <родительский класс> :: <свойства>;
.
class Dog : private Animals {
public:
int count_dogs() {
return dogs; // использовали переменную dog
}
Animals :: set_dogs;
};
int main() {
Dog jack;
int k;
cout << "Введите количество собак: "; cin >> k;
jack.set_dogs(k);
cout << "Количество собак равняется: "<< jack.count_dogs();
return 0;
}
- В строке 6: получили доступ к функции set_dogs().
- В строке 15 - 16: отсылаем количество собак и потом их выводим.
protected - идентичен private, но свойства public переходит в доступ protected.
Как себя ведут модификаторы доступа при разных модификаторах наследования:
- Модификатор наследования public: public -> public, private -> public, protected -> protected
- Модификатор наследования private: public -> нет доступа, private -> нет доступа, protected -> нет доступа
- Модификатор наследования protected: public -> protected, private -> protected, protected -> protected