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

Сайт не является учебником по программированию. Это только небольшой авторский сборник информации в помощь начинающим программистам.

Если от класса наследуются потомки, а внутри класса есть виртуальные функции, то нужно в класс добавлять виртуальный деструктор.

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

  • Виртуальная функция — это функция, объявленная с ключевым словом virtual в базовом классе и переопределенная в одном или в нескольких производных классах.

Это вы и наблюдаете. Внутри потомков одноимённость функции переопределяет функцию родительского класса. Немного напоминает перегрузку функций, но в то же время отличается.

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

  • Если объект производного класса вызывается с помощью указателя или ссылки на него, С++ определяет какую функцию вызвать, основываясь на типе объекта

По этой причине использованы указатели. После того, как почва для работы с экземплярами объектов подготовлена, можно создать указатель на родительский класс. Так, в примере создан указатель на общий класс "Sport". Этим указателем удобно манипулировать, указывая им на любой свой производный класс (на любое своё дитя). После навязывания указателю нужного детёныша можно работать с этим указателем как будто это и не указатель, а непосредственно экземпляр того самого детёныша.

Если же детёныш указателю на родительский класс не навязан, то будет вызвана функция из родительского класса. Это происходит при первом выводе информации, там детёныша ещё навязать не успели.

Вот ещё один пример:

Здесь создаётся переменная, тип который соответствует типу дитя. Без указателя, обычная переменная. Далее уже создаётся два указателя, которые указывают на эту созданную переменную. Фактически два разных типа, но тем не менее указателем на родительский класс можно указывать на детей.

В первом случае происходит два обращения к основному классу. Логично, что там, где есть virtual, там вызывается виртуальная функция, а там, где нет — там вызывается не виртуальная.

Во втором случае в начале идёт обращение к дитя. К классу, унаследованному от класса Sport. Здесь функции не предшествует ключевое слово virtual, но тем не менее вызывается виртуальная функция. На это стоит обратить внимание. Связано это с тем, что virtual присутствует в породившем классе. В главном классе, от которого текущий класс происходит. Этого достаточно, чтобы во всех детях такого класса одноимённые функции стали виртуальными. В конце уже вызывается не виртуальная функция. Здесь всё просто: virtual нету ни в самом классе перед функцией, ни в породившем его классе.

  • Нельзя объявить глобальные статические функции Виртуальными.
  •  

  • Ключевое слово virtual может использоваться при объявлении переопределяемой функции в производном классе, но это необязательно: переопределение виртуальных функций всегда является виртуальным.
  •  

  • Виртуальные функции в базовом классе должны быть указаны, если они не объявлены с помощью чистого спецификатора.
  •  

  • Механизм вызова виртуальной функции может быть подавлен путём явного указания имени функции с помощью оператора разрешения области действия (::).

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

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

Ваш e-mail не будет опубликован.

Поиск

 
     

Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок