C++ для начинающих Виртуальные функции Поверхностное знакомство

Знакомство с виртуальными функциями у начинающих программистов может быть слегка проблематичным. Возникает много простых вопросов, на которые сходу трудно дать полноценные ответы.
Первый такой вопрос: "Зачем использовать виртуальные функции?"
Чтобы ответить на этот вопрос, для начала нужно понять, что существует два механизма определения поведения функций:

  • Переопределение методов базового класса в производном классе.
  • Использование виртуальных функций.
С переопределением функции вы скорее всего уже знакомы.

В листинге #1 и у объекта, зарождённого от базового класса, и у объекта зарождённого от наследника имеется функция, названная print. Поскольку функция описана и для базового класса (класса Alphabet) и для потомка того класса (класса A), то при запросе конкретного объекта воспроизводится соответствующая непосредственному типу объекта. Это называется переопределением по одной простой причине. Если бы мы не описывали поведение функции в наследнике, то несмотря на видимость отсутствия функции внутри наследника, функция в наследнике всё равно имела бы место, но поведение её соответствовало бы поведению базового класса. Добавим в основной объект функцию info, а в объекте-наследнике ничего дописывать не станем.

Функция осного класса была унаследована потомком, и поэтому несмотря на то что никакого обозначения функции info() в классе A нет, объекты класса A умеют вызывать функцию, определённую для родительского по отношению к себе класса, и поведение той функции будет таким же как оно у родительского класса. Поскольку в листинге #1 подобное поведение функции print() перекрыто дополнительным описанием функции print() непосредственно внутри класса-потомка (класса A), то в листинге #1 происходит переопределение функции. Т. е. переопределением мы переиначиваем поведение одноимённой функции, распологающейся в родительском классе. Функция info() не переиначивается, следовательно переопределения её нет.
Переопределение в некоторой степени похоже на перегрузку функций, но это принципиально разные понятия. В противовес перегрузке в переопределении в объявлении функции совпадает всё: и название, и количество параметров, и тип каждого параметра.
Теперь, когда мы понимаем, что такое переопределение функции, нам проще понять, что дают виртуальные функции. Но для начала перепишем листинг #1 задействуя указательные переменные. Изменений будет мало:


Как вы можете догадаться, поскольку тип у указательной переменной Alphabet, то и вызывает она функцию print() из класса Alphabet, отчего несмотря на то, что указательная переменная перенаправляется в объект-потомок, переопределение не срабатывает.
Для решения вот такой проблемы как раз и нужны виртуальные функции. Если используем обычные функции, то компилятор использует первую встреченную сверху по иерархии классов. Если иерархия классов достаточно глубокая, то, как выше было уже пояснено, откуда-то наследством вполне могла прийти обычная функция. Внесём изменение, допишем, что в классе-родителе функция виртуальная:

Теперь при перенаправлении указателя на потомка, компилятор выбирает функцию именно того потомка, на который указатель указывает. Сколько бы потомков у класса Alphabet не было, для каждого из них будет происходить именно тот вызов функции, который ближе всех выбранному указателем потомку.
  • Если в базовом классе есть функция с ключевым словом virtual, то такой класс называется полиморфным, а все функции внутри потомков (которые предполагается переопределить) называются виртуальными.
  • То, какая виртуальная функция будет вызвана, определяется во время выполнения программы.
  • Виртуальная функция должна быть членом класса для которого определяется, а не "другом", но в то же время виртуальная функция может быть другом иного класса.
  • Функциям деструкторов разрешается быть виртуальными, а функциям конструкторов нет.

Один комментарий на «“C++ для начинающих Виртуальные функции Поверхностное знакомство”»

  1. Аноним:

    Очень помогло, для новичков сложно что-то найти на эту тему, спасибо!

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

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

Поиск

 
     

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

https://www.litres.ru/pol-deytel/android-dlya-programmistov-sozdaem-prilozheniya-4840674/?lfrom=15589587

Последние комментарии

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