2010-04-03 3 views
16

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

-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.

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

+1

Вы пробовали частное или защищенное наследство? Изменяет ли он диагностику? – Tomek

+0

Это отличная идея. Но, к сожалению, это не так. –

+1

'-WeffC++' вызывает множество бессмысленных (как и библиотек) предупреждений из стандартной библиотеки, и об этом упоминается [в FAQ] (http://gcc.gnu.org/onlinedocs/libstdc++/faq.html # faq.wefcxx_verbose) –

ответ

23

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

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

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

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

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

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

Точно.

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

9

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

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

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

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

это будет:

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

+0

Hmm .. хорошо пункт. Деструктор 'enable_shared_from_this' фактически защищен. Так, возможно, это ошибка в «-WeffC++» GCC? –

+2

@ Shtééf: Эффективный C++ говорит, что полиморфные базы должны иметь виртуальные dtors, а классы, не предназначенные для полиморфизма, не должны иметь виртуальных dtors. Поскольку компилятор не может сказать, что именно, я бы сказал, что да, это ошибка, чтобы предложить это предупреждение. Так что либо ваша реализация IIRC дает рекомендации относительно защищенных dtors в неполиморфных базовых классах, если из GotW/Exceptional C++, а не Effective. –

+2

Кроме того, моя версия man-страницы gcc говорит, что предупреждение '-Wnon-virtual-dtor' предназначено только для классов с виртуальной функцией. Таким образом, либо 'enable_shared_from_this' имеет виртуальную функцию (моя реализация не работает), либо предупреждение не соответствует документации (что было бы ошибкой), иначе документы изменились (проверьте, может быть, они объясняют предупреждение в дальнейшем). На самом деле возможно, что * Эффективный C++ * был обновлен - страница gcc man цитирует названия, которые не соответствуют моему третьему изданию.Так что, возможно, это ошибка в книге Скотта Мейерса ;-) –

4

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

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

я правильно полагая, что это деструктор является поддельным, или есть реальная цель этого?

Нет, это не подделка и имеет настоящую цель. Если он не был определен, он был бы объявлен как неявный как public, чтобы исключить его явно объявленное как protected.

Смежные вопросы