Почему enable_shared_from_this имеет не виртуальный деструктор? - PullRequest
17 голосов
/ 03 апреля 2010

У меня есть любимый проект, с которым я экспериментирую с новыми функциями C ++ 11. Хотя у меня есть опыт работы с C, я довольно плохо знаком с C ++. Чтобы освоить лучшие практики (помимо большого чтения), я включил некоторые строгие параметры компилятора (используя GCC 4.4.1):

-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors

Это хорошо сработало для меня. До сих пор мне удавалось устранить все препятствия. Тем не менее, мне нужно enable_shared_from_this, и это вызывает у меня проблемы. При компиляции моего кода я получаю следующее предупреждение (в моем случае ошибка) (вероятно, вызвано -Weffc++):

base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor

Так что, в принципе, я немного ошибаюсь в этой реализации enable_shared_from_this, потому что:

  • Деструктор класса, который предназначен для подклассов должен всегда быть виртуальным, ИМХО.
  • Деструктор пуст, зачем его вообще?
  • Не могу представить, чтобы кто-нибудь захотел удалить свой экземпляр по ссылке enable_shared_from_this.

Но я ищу способы справиться с этим, так что мой вопрос действительно, есть ли правильный способ справиться с этим? И: правильно ли я считаю, что этот деструктор фальшивый или в этом есть реальная цель?

Ответы [ 3 ]

24 голосов
/ 03 апреля 2010

Деструктор класса, который предназначен для создания подклассов, всегда должен быть виртуальным, ИМХО.

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

Наличие любой виртуальной функции в классе, включая деструктор, требует дополнительных затрат. Boost (и стандартная библиотека TR1 и C ++ 11) не хочет заставлять вас использовать эти издержки только потому, что вам нужно иметь возможность получить shared_ptr из указателя this.

Деструктор пуст, зачем его вообще?

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

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

Точно.

Что касается предупреждения компилятора, я бы проигнорировал предупреждение или подавил его (с комментарием в коде, объясняющим, почему вы это делаете). Иногда, особенно на «педантичных» уровнях предупреждений, предупреждения компилятора бесполезны, и я бы сказал, что это один из таких случаев.

9 голосов
/ 03 апреля 2010

Я согласен с описанием Джейм, но добавил бы

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

Так что я бы изменил

Деструктор класса, который предназначен для подкласса должен всегда быть виртуальным, ИМХО.

это будет:

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

4 голосов
/ 06 мая 2012

Есть ли правильный способ справиться с этим?

Не используйте -Weffc++ все время. Иногда полезно включить его, чтобы проверить код, но не использовать его постоянно. Это дает ложные срабатывания и на самом деле не поддерживается в эти дни. Используйте его время от времени, но помните, что вам, возможно, придется игнорировать некоторые предупреждения. В идеале, просто запомните все советы в книгах Мейерса, и тогда вам все равно это не нужно; -)

Правильно ли я считаю, что этот деструктор фальшивый, или у него есть реальная цель?

Нет, это не фальшивка и имеет реальную цель. Если бы он не был определен, он был бы объявлен как «1011», чтобы предотвратить его явное объявление protected.

...