Страницы

Поиск по вопросам

понедельник, 1 октября 2018 г.

virtual и override

Просматривая различные примеры (один из них: Лекция. Виртуальные функции и полиморфизм), увидел, что при использовании virtual можно переопределять метод производного класса. Также увидел, что даже если ссылаться на исходный класс — все равно будет вызван метод, переопределенный в дочернем классе, только если не указана область видимости метода.
Но (!) Я копаю кучу исходников С++ и вижу, что когда переопределяют метод в дочернем классе, то добавляют слово override. Однако в вышепоказанном примере никто override не пишет.
Так нужен он или нет? И вообще, что он дает, этот override? Везде написано, что он указывает на то что, метод переопределен, но в примерах его никто не использует, а в исходниках я его встречаю строго постоянно.
Помогите разобраться поконкретнее , virtual и override в С++ используются всегда только в паре или не всегда? И если не всегда в паре, то как это вообще влияет на выполнение кода?
Я просто пишу код и у меня выбивает ошибка на чтение нулевого адреса. Я думаю что что-то напортачил с этими виртуальными методами, хотя делаю все по шаблону.


Ответ

virtual используется в базовом классе, чтобы сделать функцию виртуальной (полиморфной).
struct A { void f(); // обычная функция };
struct B : A { virtual void f(); // виртуальная функция (перекрывает обычную A::f) virtual void g() = 0; // чисто-виртуальная функция };
Также virtual можно, но не обязательно использовать в классах-потомках
struct C1 : B { void f(); // виртуальная, т.к. B::f виртуальная void g() = 0; // все еще чисто-виртуальная функция };
struct C2 : B { virtual void f(); // виртуальная, т.к. B::f виртуальная virtual void g() = 0; // все еще чисто-виртуальная функция };
override используется в классе-потомке, чтобы указать что функция должна переопределять виртуальную функцию, объявленную в базовом классе. Это позволяет избавиться от ошибок, когда из-за опечатки вместо переопределения существующей виртуальной функции была создана новая (с другим именем или сигнатурой).
struct C3 : B { void f() override; // гарантированное переопределение B::f void g() override = 0; };
Допускается, но не рекомендуется использование virtual совместно с override
struct C4 : B { // virtual не имеет смысла, т.к. override подразумевает virtual. virtual void f() override; };
Кроме override существует ключевое слово final, которое запрещает переопределение виртуальной функции в классах-потомках.
struct C5 : B { virtual void f() final; };

Комментариев нет:

Отправить комментарий