Почему у enable_shared_from_this есть не виртуальный деструктор?
У меня есть проект для домашних животных, с которым я экспериментирую с новыми функциями С++ 11. Хотя у меня есть опыт работы с 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
, потому что:
- Деструктор класса, который предназначен для подкласса, всегда должен быть виртуальным, IMHO.
- Деструктор пуст, зачем он вообще?
- Я не могу представить, чтобы кто-то захотел удалить свой экземпляр ссылкой
enable_shared_from_this
.
Но я ищу способы справиться с этим, так что мой вопрос в самом деле, есть ли подходящий способ справиться с этим? И: Правильно ли я полагаю, что этот деструктор фиктивный, или есть реальная цель?
Ответы
Ответ 1
Деструктор класса, который предназначен для подкласса, всегда должен быть виртуальным, IMHO.
Виртуальный деструктор в базовом классе необходим только в том случае, если экземпляр производного класса будет удален с помощью указателя на базовый класс.
Наличие любой виртуальной функции в классе, включая деструктор, требует накладных расходов. Boost (и стандартная библиотека TR1 и С++ 11) не хочет заставлять вас иметь накладные расходы только потому, что вам нужно получить shared_ptr
от указателя this
.
Деструктор пуст, зачем его вообще?
Если у вас нет пользовательского конструктора, компилятор предоставляет его для вас, поэтому это не имеет большого значения.
Я не могу представить, чтобы кто-то захотел удалить свой экземпляр ссылкой enable_shared_from_this
.
Совершенно верно.
Что касается предупреждения компилятора, я бы проигнорировал это предупреждение или подавил его (с комментарием в коде, объясняющим, почему вы это делаете). Иногда, особенно на уровнях "педантичного" предупреждения, предупреждения компилятора бесполезны, и я бы сказал, что это один из этих случаев.
Ответ 2
Я согласен с описанием Jame, но добавил бы
Виртуальный деструктор требуется только в том случае, если вы хотите уничтожить экземпляр этого класса практически. Это не всегда так, однако, если базовый класс не предназначен для уничтожения, он должен защищать его.
Поэтому я бы изменил
Деструктор класса, который предназначенная для подкласса, всегда должна быть виртуальным, ИМХО.
это:
Деструктор класса, который предназначенные для подкласса, должны всегда виртуальный или защищенный.
Ответ 3
Есть ли правильный способ справиться с этим?
Не используйте -Weffc++
все время. Полезно иногда включать его, чтобы проверить свой код, но не использовать его надолго. Он дает ложные срабатывания и в наши дни не поддерживается. Используйте его время от времени, но помните, что вам, возможно, придется игнорировать некоторые предупреждения. В идеале просто запомните все советы в книгах Meyers, а затем вам это не понадобится; -)
Я правильно понял, что этот деструктор является фиктивным, или есть реальная цель для него?
Нет, это не подделка и имеет настоящую цель. Если он не был определен, он будет объявлен как неявный как public
, чтобы исключить его явно как protected
.