Здравствуйте, sergey2b, Вы писали:
S>как вы считаете нужно ли декларировать виртуальный деструктор S>в наследуемом классе, если он уже задекларирован в родители
Его и не получится не декларировать, если он нужен в конкретном наследнике.
А если не нужен, то к чему оно всё?
Re[2]: нужно ли декларировать виртуальный деструктор
Здравствуйте, fk0, Вы писали:
fk0> Его и не получится не декларировать, если он нужен в конкретном наследнике. fk0>А если не нужен, то к чему оно всё?
если достаточно виртуального деструктора по умолчанию то можно не декларировать
но с другой стороны тогда придеться смотреть в родители есть ли вертуальный деструктор или нет
что бы понять какой диструктор в текущем наследуем классе
Здравствуйте, fk0, Вы писали:
fk0> Его и не получится не декларировать, если он нужен в конкретном наследнике.
Получится. Если деструктор базового класса объявлен виртуальным, то деструкторы всех производных классов также будут виртуальными, независимо от того, как они объявлены:
Я считаю аналогично но меня уверяют что декларировать не надо
Аргумент, не надо увеличивать исходник
Мой аргумент не надо проверять декларацию родительского класса
Re[3]: нужно ли декларировать виртуальный деструктор
Здравствуйте, sergey2b, Вы писали:
S>Я считаю аналогично но меня уверяют что декларировать не надо S>Аргумент, не надо увеличивать исходник S>Мой аргумент не надо проверять декларацию родительского класса
Ну я с тобой полностью согласен. И я бы стоял на своем в этой ситуации.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: нужно ли декларировать виртуальный деструктор
Здравствуйте, sergey2b, Вы писали:
S>Я считаю аналогично но меня уверяют что декларировать не надо S>Аргумент, не надо увеличивать исходник S>Мой аргумент не надо проверять декларацию родительского класса
Скорее всего, твои оппоненты застряли во времени лет на 20 назад и не прочувствовали разницы между virtual и override. От virtual в деструкторе производного класса толку действительно не очень много — можно объявить виртуальным деструктор производного класса, но забыть это сделать в базовом классе, и компилятор это спокойно пропустит. Другими словами, даже если ты видишь в деструкторе производного класса virtual, это вовсе не означает, что деструктор базового класса также виртуальный. Все равно придется заглядывать в базовый класс. И совсем другое дело override — это дает гарантию того, что деструктор базового класса виртуальный.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, 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 на строчку кода.
Здравствуйте, 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).
Здравствуйте, sergey2b, Вы писали:
S>как вы считаете нужно ли декларировать виртуальный деструктор
Через override норм, в конце-концов есть = default. Аргумент — мы пишем код для себя и некоторых случаях для компилятора, а для себя лучше всего видеть что происходит избегать неявного.
S>с точки зрения хороших практик
Вроде ты проходил через. Просят не объявлять — не объявляй. Зачем спорить?
Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?
Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.
Re[3]: нужно ли декларировать виртуальный деструктор
Здравствуйте, sergey2b, Вы писали:
fk0>> Его и не получится не декларировать, если он нужен в конкретном наследнике. fk0>>А если не нужен, то к чему оно всё?
S>если достаточно виртуального деструктора по умолчанию то можно не декларировать S>но с другой стороны тогда придеться смотреть в родители есть ли вертуальный деструктор или нет S>что бы понять какой диструктор в текущем наследуем классе
А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может
поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального
деструктора -- это проблема.
Здравствуйте, Quebecois, Вы писали:
Q>Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?
Q>Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.
да ну так уж прогибаться под чужие причуды — перебор. Ревьюверы обычно находятся где-то рядом в списках на сокращение — такие же трудяги. Даже если это не так, не факт, что соглашательская позиция послужит плюсом в карму.
Здравствуйте, sergii.p, Вы писали:
SP>да ну так уж прогибаться под чужие причуды — перебор. Ревьюверы обычно находятся где-то рядом в списках на сокращение — такие же трудяги. Даже если это не так, не факт, что соглашательская позиция послужит плюсом в карму.
Ну, блин
Мне это напоминает моих детей младшего школьного возраста, готовых до крика спорить и обижаться друг на друга по поводу того, чей киндер-сюрприз оказался круче.
Золотое правило дипломатии: делаем уступки в неважных вопросах, чтобы потом выбить себе уступку в важном. Или, другими словами, любой каприз за ваши деньги. Улыбаемся и соглашаемся по мелочам, но не забываем тащить в продукт решения, от которых увеличивается собственное влияние. Как-то так.
Здравствуйте, Quebecois, Вы писали:
Q>Цель у тебя какая? Принести максимум справедливости в мир C++, или максимум денег с работы домой?
Q>Если цель вторая, то составь в OneNote табличку "список местных причуд" и сверяйся с ней перед каждым коммитом. Это хорошо продвинет твою задницу вниз в списке на следующее сокращение.
Почему ты думаешь, что списки на сокращение составляет не он? Может, какие-то ньюкамеры пытаются вкрутить ему в голову какие-то свои взгляды на жизнь и от него теперь зависит их дальнейшая судьба. А к нам он зашел посоветоваться, просто потому что не хочет рубить с плеча.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Почему ты думаешь, что списки на сокращение составляет не он? Может, какие-то ньюкамеры пытаются вкрутить ему в голову какие-то свои взгляды на жизнь и от него теперь зависит их дальнейшая судьба. А к нам он зашел посоветоваться, просто потому что не хочет рубить с плеча.
я обычный senior developer которому зачем то дали сделать code review ода который написал наш principal developer
Здравствуйте, fk0, Вы писали:
fk0> А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может fk0>поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального fk0>деструктора -- это проблема.
А вы не путаете лошадь и телегу? Не может просто так завтра поменяться базовый класс. Базовый класс (или интерфейс) — это контракт, на основании которого строится весь остальной код. Наличие виртуального деструктора — это часть этого контракта. И писать код, который на этот контракт опирается, вроде как вполне нормально.
struct Base1 { virtual ~Base1() = default; };
using Base = Base1;
struct Derived: Base {};
...
std::vector<std::unique_ptr<Base>> instances;
Это самый что ни на есть идиоматичный способ реализации полиморфизма и его корректность зависит от наличия виртуального деструктора.
Re[5]: нужно ли декларировать виртуальный деструктор
Здравствуйте, sergii.p, Вы писали:
fk0>> А такое понимание не нужно и даже вредно. Потому, что завтра базовый класс может fk0>>поменяться, и если кто-то написал такой код, который зависит от наличия (не) виртуального fk0>>деструктора -- это проблема.
SP>А вы не путаете лошадь и телегу? Не может просто так завтра поменяться базовый класс. Базовый класс (или интерфейс) — это контракт,
Открываю редактор, меняю, делаю безобидный коммит. И никто не заметит. А где там лошадь, а где телега -- десятое дело.
Не говоря уж о том, что цепочка наследования может быть лихо закрученной через пять шаблонов и концов там не найдёшь.