LINUX.ORG.RU

C++ виртуальные деструкторы (ну простите)

 , , ,


0

2

Добрый день. Тема поднималась хренову тучу раз, уж простите. Вопрос: объявляете ли вы деструкторы производных классов виртуальными? Я знаю, что не обязательно, что и так будет работать. Тут вопрос скорее такой: с точки зрения правил хорошего тона нужно ли это делать?

★★★★

Начиная с C++11 унаследованные и переопределённые виртуальные методы (в том числе виртуальные деструкторы) следует помечать override, а не virtual. И профит вполне очевидный - если вы ошибётесь где-нибудь в сигнатуре/названии метода (для деструкторов не актуально, но всё же) и на самом деле ничего не переопределите, то компилятор даст вам по рукам. А пометка как virtual ни от чего не защищает и только несёт немного доп. информации кодеру.

KivApple ★★★★★ ()
Последнее исправление: KivApple (всего исправлений: 1)

Вопрос: объявляете ли вы деструкторы производных классов виртуальными?

Да, так синтаксис лучше соответствует семантике.

xaizek ★★★★★ ()

Просто разложи вопрос на два:

  • Объявлять ли функции виртуальными?
  • Определять ли деструктор самому(или достаточно синтезируемого)?
dllmain ()

C.128: Virtual functions should specify exactly one of virtual, override, or final

Reason

Readability. Detection of mistakes. Writing explicit virtual, override, or final is self-documenting and enables the compiler to catch mismatch of types and/or names between base and derived classes. However, writing more than one of these three is both redundant and a potential source of errors.

It's simple and clear:

  • virtual means exactly and only «this is a new virtual function.»
  • override means exactly and only «this is a non-final overrider.»
  • final means exactly and only «this is a final overrider.»

If a base class destructor is declared virtual, one should avoid declaring derived class destructors virtual or override. Some code base and tools might insist on override for destructors, but that is not the recommendation of these guidelines.

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#...

AlexVR ★★★★★ ()

Я например исходя из применения класса поступаю. Если предполагается что производный класс будет храниться в указателях или ссылках на базу - то делаю вирт деструктор (если он конечно вообще нужен, недефолтный).

Ну и вообще не редко в литературе видел рекомендацию «если есть хотя бы один вирт.метод - то деструктор рекомендуется виртуальный , даже если тело деструктора будет пусто» - зачем это так сейчас не вспомню, но факт что такая рекомендация существует.

bonta ()
Ответ на: комментарий от bonta

зачем это так сейчас не вспомню

Если есть виртуальная функция, это значит, что кто-то будет её вызывать через указатель на базовый класс.

А раз есть такой указатель, то когда-нибудь через него будут освобождать память.

И при освобождении нужен будет деструктор. Лучше виртуальный. Иначе страшные бедствия в виде неосвобождения ресурсов и развала концепции RAII.

Einstok_Fair ★★ ()
Ответ на: комментарий от bonta

Я например исходя из применения класса поступаю. Если предполагается что производный класс будет храниться в указателях или ссылках на базу - то делаю вирт деструктор (если он конечно вообще нужен, недефолтный).

Если предполагается вызов деструктора через указатель на базовый класс, деструктор должен быть виртуальным. И это не рекомендация, а следование стандарту (из описания `delete`):

if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined

Laz ★★★★ ()
Последнее исправление: Laz (всего исправлений: 1)