Виртуальные функции. Ещё один пример



  • Если от класса наследуются потомки, а внутри класса есть виртуальные функции, то нужно в класс добавлять виртуальный деструктор.
  • Если класс не предназначен для полиморфного поведения, то деструктор надо делать обычным, т. е. не виртуальным.
Смысл показанной программы в том, что есть общее понятие "спорт". Что такое спорт, мы, наверное, все знаем. Я разложил спорт на две игры. Был создан общий класс Sport, от него были унаследованы две спортивные игры: футбол и баскетбол. Всего получилось три класса: Общий родитель, два его наследника. Во всех трёх классах присутствует одноимённая функция show_info(), показывающая информацию. Сейчас неважно, что там написано, важно только увидеть, что за класс срабатывает, поэтому выбраны простые обозначения для наглядности. Различаются эти функции только тем, что внутри базового класса функции предшествуют ключевое слово virtual.
  • Виртуальная функция — это функция, объявленная с ключевым словом virtual в базовом классе и переопределенная в одном или в нескольких производных классах.
Это вы и наблюдаете. Внутри потомков одноимённость функции переопределяет функцию родительского класса. Немного напоминает перегрузку функций, но в то же время отличается. Для нас сейчас основной интерес представляют унаследованные классы. Как можно видеть в примере, сначала созданы экземпляры от унаследованных классов.
  • Если объект производного класса вызывается с помощью указателя или ссылки на него, С++ определяет какую функцию вызвать, основываясь на типе объекта.
По этой причине использованы указатели. После того, как почва для работы с экземплярами объектов подготовлена, можно создать указатель на родительский класс. Так, в примере создан указатель на общий класс "Sport". Этим указателем удобно манипулировать, указывая им на любой свой производный класс (на любое своё дитя). После навязывания указателю нужного детёныша можно работать с этим указателем как будто это и не указатель основного типа, а непосредственно указатель на экземпляр того самого детёныша. Если же детёныш указателю на родительский класс не навязан, то будет вызвана функция из родительского класса.
В показанном коде детёныша мы навязать не успели на момент первого вывода информации на экран.
Вот ещё один пример:

В листинге #2 создаётся переменная, тип который соответствует типу дитя. Без указателя, обычная переменная. Далее уже создаётся два указателя, которые указывают на эту созданную переменную. Фактически два разных типа, но тем не менее указателем на родительский класс можно указывать на детей.
В первом случае в листинге #2 происходит два обращения к основному классу. Логично, что там, где есть virtual, там вызывается виртуальная функция, а там, где нет — там вызывается не виртуальная.
Во втором случае в листинге #2 в начале идёт обращение к дитя. К классу, унаследованному от класса Sport. Здесь функции не предшествует ключевое слово virtual, но тем не менее вызывается виртуальная функция. На это стоит обратить внимание. Связано это с тем, что virtual присутствует в породившем классе. В главном классе, от которого текущий класс происходит. Этого достаточно, чтобы во всех детях такого класса одноимённые функции стали виртуальными. В конце уже вызывается не виртуальная функция. Здесь всё просто: virtual нету ни в самом классе перед функцией, ни в породившем его классе.
  • Нельзя объявить глобальные статические функции виртуальными.
  • Ключевое слово virtual может использоваться при объявлении переопределяемой функции в производном классе, но это необязательно: переопределение виртуальных функций всегда является виртуальным.
  • Виртуальные функции в базовом классе должны быть явно указаны, если они не объявлены с помощью чистого спецификатора.
  • Механизм вызова виртуальной функции может быть подавлен путём явного указания имени функции с помощью оператора разрешения области действия (::).



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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Поиск

 
     

Случайная книга в электронном формате

https://www.litres.ru/robert-s-martin/chistyy-kod-sozdanie-analiz-i-refaktoring-2/?lfrom=15589587
Яндекс.Метрика