Деструктор по умолчанию может быть сгенерирован как виртуальный деструктор автоматически?

точно, в чем я нуждался. Я решил его со следующим кодом, который сохраняет последний добавленный объект видимым:

    delegate void UpdateCCNetWindowDelegate(String msg);

     private void Message2CCNetOutput(String message)
     {
         // Check whether the caller must call an invoke method when making method calls to listBoxCCNetOutput because the caller is 
         // on a different thread than the one the listBoxCCNetOutput control was created on.
         if (listBoxCCNetOutput.InvokeRequired)
         {
             UpdateCCNetWindowDelegate update = new UpdateCCNetWindowDelegate(Message2CCNetOutput);
             listBoxCCNetOutput.Invoke(update, message);
         }
         else
         {
             listBoxCCNetOutput.Items.Add(message);
             if (listBoxCCNetOutput.Items.Count > Program.MaxCCNetOutputLines)
             {
                 listBoxCCNetOutput.Items.RemoveAt(0); // remove first line
             }
             // Make sure the last item is made visible
             listBoxCCNetOutput.SelectedIndex = listBoxCCNetOutput.Items.Count - 1;
             listBoxCCNetOutput.ClearSelected();
         }
     }
53
задан lc. 12 July 2009 в 15:31
поделиться

5 ответов

Нет. Создание виртуального метода связано с определенными затратами, и в C ++ существует философия не заставлять вас платить за вещи, которые вы явно не заявляете, что хотите использовать. Если бы виртуальный деструктор был сгенерирован автоматически, вы бы заплатили цену автоматически.

Почему бы просто не определить пустой виртуальный деструктор?

46
ответ дан 7 November 2019 в 08:29
поделиться

Нет, все деструкторы по умолчанию НЕ виртуальные.

Вам нужно будет определить виртуальный деструктор для всех базовых классов

В дополнение к этому.

Цитата Скотта Мейерса из его книги «Эффективный C ++» ":

Стандарт языка C ++ - необычно ясно по этой теме. когда вы пытаетесь удалить производный класс объект через указатель базового класса а базовый класс имеет не виртуальный деструктор (как и EnemyTarget), результаты не определены

На практике обычно рекомендуется определять класс с помощью виртуального деструктора, если вы думаете, что кто-то может в конечном итоге создать из него производный класс. Я все равно стараюсь сделать так, чтобы все классы имели виртуальный деструктор. Да, это связано с определенными затратами, но цена отказа от того, чтобы сделать его более частым и виртуальным, взвешивает незначительные накладные расходы времени выполнения.

Я предлагаю, делайте его не виртуальным только тогда, когда вы абсолютно уверены, что вы этого хотите, а не полагаться на невиртуальные значения по умолчанию, которые применяют компиляторы. Вы можете не согласиться, однако (в итоге) у меня недавно произошла ужасная утечка памяти в каком-то унаследованном коде, где все, что я сделал, это добавил std :: vector в один из классов, которые существовали в течение нескольких лет. Оказывается, один из его базовых классов не t имеет определенный деструктор (деструктор по умолчанию пустой, не виртуальный!), и поскольку память не выделялась таким образом, прежде чем утечка памяти до этого момента. Многие дни расследования и время потрачено впустую ...

9
ответ дан 7 November 2019 в 08:29
поделиться

Вам необходимо объявить его виртуальным.

1
ответ дан 7 November 2019 в 08:29
поделиться

Да, путем наследования от базового класса с помощью виртуального деструктора. В этом случае вы уже платите цену за полиморфный класс (например, vtable).

9
ответ дан 7 November 2019 в 08:29
поделиться

Ури и Майкл правы - я просто добавлю, что если вас беспокоит то, что вам нужно прикоснуться к двум файлам, чтобы объявить и определить деструктор, совершенно нормально определить минимальный встроенный в заголовке:

class MyClass
{
   // define basic destructor right here
   virtual ~MyClass(){}

   // but these functions can be defined in a different file
   void FuncA();
   int FuncB(int etc);
}
8
ответ дан 7 November 2019 в 08:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: