TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #283 3.68K
Идентификатор final для виртуальных методов
#новичкам

Продолжаем серию постов! Ранее мы уже упоминали идентификатор со специальным значением final в рамках наследования классов — запрещали создавать наследников того или иного класса. Это поведение распространялось на весь класс целиком, в том числе и на все его методы. Это может быть слишком строгим ограничением в какой-то ветке нашего подсемейства. Например, мы хотим его продолжать развивать, но точечно зафиксировать поведение одного конкретного переопределенного метода.

Запретить переопределение метода в наследниках можно с помощью идентификатора final (С++ 11 и выше):
struct Child : public Parent
{
void method_name() override final;
};

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

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

В качестве примера, давайте рассмотрим семейство датчиков умного дома. Пусть была разработана открытая библиотека, которая предоставляет некоторый набор интерфейсов для разных типов датчиков. Например, для подсемейства пожарных датчиков. Производители устройств могут наследовать специальный интерфейс и реализовать прошивку для своего девайса. Как у них работает этот сенсор — никто не знает, но главное, что в случае срабатывания такого датчика происходит важное, в рамках этого подсемейства, действие - вызывается бригада пожарных. Это достаточно важный смысл, который может быть заложен в наследника класса и ограничен в переопределении для производителя:
// Датчик возгорания
struct IFireSensor : public ISensor
{
// В случае срабатывания, вызываем пожарных
void onAlarm(control_panel_t *ctrl) override final
{
ctrl->call_fireman();
}
};

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

Конечно, можно написать комментарии к коду, в надежде, что их прочитают... Но вот практика показывает, что их периодически игнорируют. Если какое-то ограничение не срабатывает во время компиляции и доходит до ревью, то разработка затягивается. Пока это увидят, пока переделают... Да и вообще, это сработает, только если у проверяющего достаточно компетенций / внимательности.

Кстати, хоть final и может быть применён только к виртуальному методу, мы не можем с помощью него проверить действительно ли мы переопределяем метод. Идентификатор final может быть применён к новому объявленному методу, а override нельзя. Следовательно, мы можем добиться такой ситуации: живой пример.

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

#cppcore #cpp11
Telegram Грокаем C++ Всем привет! Мы в очередной раз подготовили серию грокательных постов о простом и не очень. В ближайшее время нас ждут следующие посты: 1. Память наследованных классов 2. Память виртуально наследованных классов 3. Девиртуализация доступа к полям виртуально…
  • 🔥 18
  • 👍 6
  • 🏆 3
  • ❤ 2
  • ⚡ 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →