Подтвердить что ты не робот

Почему у 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.

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Совершенно верно.

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

Ответ 2

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

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

Поэтому я бы изменил

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

это:

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

Ответ 3

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

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

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

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