Просматривая различные примеры (один из них: Лекция. Виртуальные функции и полиморфизм), увидел, что при использовании 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 }