нужно ли декларировать виртуальный деструктор
От: sergey2b ЮАР  
Дата: 27.04.24 16:18
Оценка:
как вы считаете нужно ли декларировать виртуальный деструктор
в наследуемом классе, если он уже задекларирован в родители

с точки зрения хороших практик
Re: нужно ли декларировать виртуальный деструктор
От: fk0 Россия https://fk0.name
Дата: 27.04.24 16:41
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>как вы считаете нужно ли декларировать виртуальный деструктор

S>в наследуемом классе, если он уже задекларирован в родители

Его и не получится не декларировать, если он нужен в конкретном наследнике.
А если не нужен, то к чему оно всё?
Re[2]: нужно ли декларировать виртуальный деструктор
От: sergey2b ЮАР  
Дата: 27.04.24 16:47
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Его и не получится не декларировать, если он нужен в конкретном наследнике.

fk0>А если не нужен, то к чему оно всё?

если достаточно виртуального деструктора по умолчанию то можно не декларировать
но с другой стороны тогда придеться смотреть в родители есть ли вертуальный деструктор или нет
что бы понять какой диструктор в текущем наследуем классе
Re: нужно ли декларировать виртуальный деструктор
От: rg45 СССР  
Дата: 27.04.24 23:35
Оценка: +8
Здравствуйте, sergey2b, Вы писали:

S>как вы считаете нужно ли декларировать виртуальный деструктор


Считаю, что лучше декларировать, но только как override, а не virtual. Это не позволит забыть объявить виртуальным деструктор базового класса.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: нужно ли декларировать виртуальный деструктор
От: rg45 СССР  
Дата: 27.04.24 23:42
Оценка: +2
Здравствуйте, fk0, Вы писали:

fk0> Его и не получится не декларировать, если он нужен в конкретном наследнике.


Получится. Если деструктор базового класса объявлен виртуальным, то деструкторы всех производных классов также будут виртуальными, независимо от того, как они объявлены:

http://coliru.stacked-crooked.com/a/235da121d2be076f

#include <iostream>
#include <memory>

class Base
{
public:
    virtual ~Base(){ std::cout << "~Base()" << std::endl; }
};

class Derived : public Base
{
public:
    /*virtual*/ ~Derived(){ std::cout << "~Derived()" << std::endl; } /*override*/
};

int main()
{
    std::unique_ptr<Base> p(new Derived());
}

g++ -std=c++20 -O2 -Wall -Wno-non-template-friend -pedantic -pthread main.cpp && ./a.out
~Derived()
~Base()
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 28.04.2024 0:08 rg45 . Предыдущая версия . Еще …
Отредактировано 27.04.2024 23:45 rg45 . Предыдущая версия .
Отредактировано 27.04.2024 23:44 rg45 . Предыдущая версия .
Re[2]: нужно ли декларировать виртуальный деструктор
От: sergey2b ЮАР  
Дата: 27.04.24 23:47
Оценка:
Я считаю аналогично но меня уверяют что декларировать не надо
Аргумент, не надо увеличивать исходник
Мой аргумент не надо проверять декларацию родительского класса
Re[3]: нужно ли декларировать виртуальный деструктор
От: rg45 СССР  
Дата: 27.04.24 23:49
Оценка: +3
Здравствуйте, sergey2b, Вы писали:

S>Я считаю аналогично но меня уверяют что декларировать не надо

S>Аргумент, не надо увеличивать исходник
S>Мой аргумент не надо проверять декларацию родительского класса

Ну я с тобой полностью согласен. И я бы стоял на своем в этой ситуации.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: нужно ли декларировать виртуальный деструктор
От: rg45 СССР  
Дата: 27.04.24 23:55
Оценка: 18 (1) +4
Здравствуйте, sergey2b, Вы писали:

S>Я считаю аналогично но меня уверяют что декларировать не надо

S>Аргумент, не надо увеличивать исходник
S>Мой аргумент не надо проверять декларацию родительского класса

Скорее всего, твои оппоненты застряли во времени лет на 20 назад и не прочувствовали разницы между virtual и override. От virtual в деструкторе производного класса толку действительно не очень много — можно объявить виртуальным деструктор производного класса, но забыть это сделать в базовом классе, и компилятор это спокойно пропустит. Другими словами, даже если ты видишь в деструкторе производного класса virtual, это вовсе не означает, что деструктор базового класса также виртуальный. Все равно придется заглядывать в базовый класс. И совсем другое дело override — это дает гарантию того, что деструктор базового класса виртуальный.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 28.04.2024 0:03 rg45 . Предыдущая версия . Еще …
Отредактировано 28.04.2024 0:01 rg45 . Предыдущая версия .
Отредактировано 27.04.2024 23:57 rg45 . Предыдущая версия .
Отредактировано 27.04.2024 23:56 rg45 . Предыдущая версия .
Re: нужно ли декларировать виртуальный деструктор
От: so5team https://stiffstream.com
Дата: 28.04.24 06:31
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

S>как вы считаете нужно ли декларировать виртуальный деструктор

S>в наследуемом классе, если он уже задекларирован в родители

S>с точки зрения хороших практик


Поставьте себя на место читающего код. Вот я, например, вижу:
class derived : public base
{
public:
  ~derived() override;
  ...
};

И у меня сразу включается триггер: раз у этого класса есть явно определенный деструктор, значит он либо владеет какими-то ресурсами, которые требуют ручного освобождения, либо он имеет какие-то side effects в своем деструкторе (скажем, вычеркивает себя из каких-то реестров). Если при этом класс derived еще и не имеет явно определенных конструкторов+операторов копирования/перемещения (или если они явно не запрещены), то это вызывает еще более пристальное внимание к классу: как так, владение какими-то ресурсами с ручной очисткой есть, а конструкторов/операторов копирования/перемещения нет?

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

Так что если деструктор для класса derived ничего не делает, то лучше его не объявлять, дабы не создавать сложностей людям вроде меня.

Отдельная история когда у нас виндовая DLL, класс derived экспортируется из нее, но содержит члены классов, которые из DLL не экспортируются.
Либо когда у нас derived работает на базе pImpl, т.е. имеет вид:
class derived : public base
{
  struct impl;
  std::unique_ptr<impl> _impl;
public:
  ~derived() override;
  ...
};

тогда с пустым телом derived::~derived все очевидно.

Ну и отдельно по поводу:
class derived : public base
{
public:
  virtual ~derived();
  ...
};

Если это в кодовой базе из далеких 1990-х, то куда ни шло.
Если в базе, уже адаптированной (или разработанной) под modern C++ (т.е. от C++11 и свежее), то тут лишние вопросы. Либо автор кода не знает современный C++ и не понимает роль ключевого слова override (и тогда можно ждать других косяков), либо здесь что-то хитрое происходит. Например, base не имеет виртуального деструктора и роль актуальной базы играет как раз derived, т.е. в коде будет не base*, а derived*. А раз что-то хитрое, значит это требует еще более пристального внимания.

В общем, резюмируя: все, что определено в коде, должно быть не просто так, а для выполнения каких-то действий. Поэтому если деструктор определяется просто для того не смотреть, есть ли деструктор в базовом классе, то это очень и очень странная мотивация. Далеко не всем она будет понятно, и далеко не все оценят ее по достоинству, т.к. подобные определения увеличивают число WTF на строчку кода.
Re: нужно ли декларировать виртуальный деструктор
От: PM  
Дата: 28.04.24 07:21
Оценка: 2 (1) +1
Здравствуйте, sergey2b, Вы писали:

S>как вы считаете нужно ли декларировать виртуальный деструктор

S>в наследуемом классе, если он уже задекларирован в родители

S>с точки зрения хороших практик


Всё просто — декларировать деструктор виртуальным, когда это нужно, и не делать этого, когда это не нужно.

Для борьбы с наследием языка добавить в систему сборки опции `-Werror=non-virtual-dtor` `-Werror=delete-non-virtual-dtor` и пусть компилятор следит за этим.

-Wnon-virtual-dtor (gcc, Clang): warns whenever a class with virtual function does not declare a virtual destructor, unless the destructor in the base class is made protected. It is a pessimistic warning, but at least you do not miss anything.

-Wdelete-non-virtual-dtor (Clang, ported to gcc too): warns whenever delete is invoked on a pointer to a class that has virtual functions but no virtual destructor, unless the class is marked final. It has a 0% false positive rate, but warns "late" (and possibly several times).

Re: нужно ли декларировать виртуальный деструктор
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 28.04.24 22:35
Оценка: 18 (1)
Здравствуйте, sergey2b, Вы писали:

S>как вы считаете нужно ли декларировать виртуальный деструктор

Через override норм, в конце-концов есть = default. Аргумент — мы пишем код для себя и некоторых случаях для компилятора, а для себя лучше всего видеть что происходит избегать неявного.

S>с точки зрения хороших практик

Вроде ты проходил через. Просят не объявлять — не объявляй. Зачем спорить?
Sic luceat lux!
Re[3]: ты будешь прав, но без работы
От: Quebecois Канада https://www.canada.ca/
Дата: 28.04.24 22:49
Оценка: 6 (1)
Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?

Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.
Re[3]: нужно ли декларировать виртуальный деструктор
От: fk0 Россия https://fk0.name
Дата: 29.04.24 08:31
Оценка: 12 (1) +1
Здравствуйте, sergey2b, Вы писали:

fk0>> Его и не получится не декларировать, если он нужен в конкретном наследнике.

fk0>>А если не нужен, то к чему оно всё?

S>если достаточно виртуального деструктора по умолчанию то можно не декларировать

S>но с другой стороны тогда придеться смотреть в родители есть ли вертуальный деструктор или нет
S>что бы понять какой диструктор в текущем наследуем классе

А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может
поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального
деструктора -- это проблема.
Re[4]: ты будешь прав, но без работы
От: sergii.p  
Дата: 29.04.24 17:25
Оценка: +1
Здравствуйте, Quebecois, Вы писали:

Q>Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?


Q>Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.


да ну так уж прогибаться под чужие причуды — перебор. Ревьюверы обычно находятся где-то рядом в списках на сокращение — такие же трудяги. Даже если это не так, не факт, что соглашательская позиция послужит плюсом в карму.
Re[5]: ты будешь прав, но без работы
От: Quebecois Канада https://www.canada.ca/
Дата: 29.04.24 22:19
Оценка: +2
Здравствуйте, sergii.p, Вы писали:

SP>да ну так уж прогибаться под чужие причуды — перебор. Ревьюверы обычно находятся где-то рядом в списках на сокращение — такие же трудяги. Даже если это не так, не факт, что соглашательская позиция послужит плюсом в карму.

Ну, блин

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

Золотое правило дипломатии: делаем уступки в неважных вопросах, чтобы потом выбить себе уступку в важном. Или, другими словами, любой каприз за ваши деньги. Улыбаемся и соглашаемся по мелочам, но не забываем тащить в продукт решения, от которых увеличивается собственное влияние. Как-то так.
Re[4]: ты будешь прав, но без работы
От: rg45 СССР  
Дата: 30.04.24 15:32
Оценка:
Здравствуйте, Quebecois, Вы писали:

Q>Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?


Q>Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.


Почему ты думаешь, что списки на сокращение составляет не он? Может, какие-то ньюкамеры пытаются вкрутить ему в голову какие-то свои взгляды на жизнь и от него теперь зависит их дальнейшая судьба. А к нам он зашел посоветоваться, просто потому что не хочет рубить с плеча.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: ты будешь прав, но без работы
От: sergey2b ЮАР  
Дата: 30.04.24 15:54
Оценка:
Здравствуйте, rg45, Вы писали:

R>Почему ты думаешь, что списки на сокращение составляет не он? Может, какие-то ньюкамеры пытаются вкрутить ему в голову какие-то свои взгляды на жизнь и от него теперь зависит их дальнейшая судьба. А к нам он зашел посоветоваться, просто потому что не хочет рубить с плеча.


я обычный senior developer которому зачем то дали сделать code review ода который написал наш principal developer
Re[6]: ты будешь прав, но без работы
От: rg45 СССР  
Дата: 30.04.24 15:58
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

S>я обычный senior developer которому зачем то дали сделать code review ода который написал наш principal developer


Ну и что он, прямо такая важная шишка, которой нельзя ничего возразить?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: нужно ли декларировать виртуальный деструктор
От: sergii.p  
Дата: 30.04.24 16:33
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может

fk0>поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального
fk0>деструктора -- это проблема.

А вы не путаете лошадь и телегу? Не может просто так завтра поменяться базовый класс. Базовый класс (или интерфейс) — это контракт, на основании которого строится весь остальной код. Наличие виртуального деструктора — это часть этого контракта. И писать код, который на этот контракт опирается, вроде как вполне нормально.

struct Base1 { virtual ~Base1() = default; };

using Base = Base1;

struct Derived: Base {};

...

std::vector<std::unique_ptr<Base>> instances;


Это самый что ни на есть идиоматичный способ реализации полиморфизма и его корректность зависит от наличия виртуального деструктора.
Re[5]: нужно ли декларировать виртуальный деструктор
От: fk0 Россия https://fk0.name
Дата: 04.05.24 09:35
Оценка:
Здравствуйте, sergii.p, Вы писали:

fk0>> А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может

fk0>>поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального
fk0>>деструктора -- это проблема.

SP>А вы не путаете лошадь и телегу? Не может просто так завтра поменяться базовый класс. Базовый класс (или интерфейс) — это контракт,


Открываю редактор, меняю, делаю безобидный коммит. И никто не заметит. А где там лошадь, а где телега -- десятое дело.
Не говоря уж о том, что цепочка наследования может быть лихо закрученной через пять шаблонов и концов там не найдёшь.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.