наследование в C++

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

Всем привет! Продолжаем изучать классы в C++. Сейчас поговорим об одном из свойств объектно ориентированного программирования — наследование.

Что такое наследование

Это принцип создание класса на базе уже существующего, при этом у нас есть возможность пользоваться функционалом (свойствами и методами) базового. Классы созданные таким образом называются производными или дочерними, а на базе которого создаются — родителем или базовым.

Этот механизм в объектно ориентированном программировании очень сильная фича. Она в несколько раз экономит время на создание проекта, а также не нагружает его повторяющимся кодом.

Производный класс мы можем усовершенствовать, добавляя:

  • Новые переменные.
  • Функции.
  • Конструкторы.

И все это не изменяя базовый класс.

наследование в c++

Например, на базе класса про животного можно создать потомка про собаку.

Модификатор доступа protected

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

наследование модификаторов c++

Если бы переменная zebras находилась в доступе private, то использование ее в функции counter_zebras привило бы к ошибке.

Как создать дочерний класс

Чтобы наследовать класс нужно использовать конструкцию ниже:

Первое на что надо обратить внимание это на двоеточие (:) оно одинарное, а не двойное как у области видимости.

Второе это <модификатор наследование>. При его оперировании можно задать какими модификаторами доступа родительского класса можно будет пользоваться в дочернем. Давайте поподробнее это разберем.

Вообщем можно указывать: public, private, protected. Из этих трех почти всегда используется public, но не плохо знать как работают другие.

Если вы новичок, то можете после информации про public перейти дальше.

public — использовать можно public и protected родительского класса. Кстати на рисунке выше изображены модификаторы доступа при использовании public.

  • В строке 20: объявили функцию public: count_dogs(), которая возвращает переменную private: dogs из animals.

private — пользоваться можно лишь свойствами (не функциями) родителя. Чтобы использовать функции нужно разрешить это напрямую (и без круглых скобок, только имя), а также разрешать нужно в публичном доступе (public). Делается это так <родительский класс> :: <свойства>;.

  • В строке 6: получили доступ к функции set_dogs().
  • В строке 15 — 16: отсылаем количество собак и потом их выводим.

protected — идентичен private, но свойства public переходит в доступ protected.

Модификатор наследования → public private protected
Модификатор доступа ↓
 public  public public  protected
 private  нет доступа нет доступа нет доступа
 protected  protected protected protected

Наследование конструктора

Наследованные конструкторы будут вызываться в порядке их наследования. Например, создали класс Earth, от него Animal, а от Animal создали Men. То вызов будет производиться так:

  1. Earth
  2. Animal
  3. Men

Для наследования конструктора нужно использовать следующую конструкцию:

  • В начале указываем имя дочернего класса — <имя класса>.
  • Далее <имя переменных конструктора> указываем столько имен переменных сколько требует этого родительский конструктор, дальше передаем базовому конструктору в скобках (<переменные конструктора>)объявленные переменные.
  • <тело> — это тело конструктора, об этом ниже.

Но чтобы все это работало, в конструкторе базового класса к переменным нужно обращаться через this->.

В строках 16 — 18: мы наследовали два конструктора, которые можем перегружать.

Если хотите подробнее познакомится c перегрузками (функций) переходите сюда.

Но может появится необходимость добавить еще одну дополнительную переменную в конструктор, которой не имеет базовый. Для этого объявляем еще одну переменную в <переменные конструктора> и делаем с ней, все что угодно в <теле>.

  • В строке 3: добавили вектор в конструктор. В этом векторе должны храниться имена собак.
  • В строке 16: объявили вектор names в котором должны хранится клички собак.
  • В строках 5 — 7: считываем имена в вектор.

Давайте посмотрим, как это работает на реальном примере:

  • В строке 5: предлагаем пользователю ввести количество собак.
  • В строке 7: создали вектор чисел vec.
  • В строке 16: объявили класс jule сразу же передав число собак и вектор и имен.
  • В строке 17: выводим все имена.
constructor.cpp
Введите количество собак: 3
Имя первой 1 собаки: Jack
Имя первой 2 собаки: Rex
Имя первой 3 собаки: Abbey
Jack, Rex, Abbey
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

Наследование деструктора

Наследованные деструкторы вызываются наоборот по сравнению с вызыванием конструктора. Если классы созданные так Earth -> Animal -> Men, то цепочка вызовов конструктора имеет такой вид:

  1. Men
  2. Animal
  3. Earth

Про деструктор можно почитать здесь.

На этом все! Если есть вопросы, то задавайте их в комментариях ниже. Удачи!


Добавить комментарий

Ваш адрес email не будет опубликован.