точно, в чем я нуждался. Я решил его со следующим кодом, который сохраняет последний добавленный объект видимым:
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();
}
}
Нет. Создание виртуального метода связано с определенными затратами, и в C ++ существует философия не заставлять вас платить за вещи, которые вы явно не заявляете, что хотите использовать. Если бы виртуальный деструктор был сгенерирован автоматически, вы бы заплатили цену автоматически.
Почему бы просто не определить пустой виртуальный деструктор?
Нет, все деструкторы по умолчанию НЕ виртуальные.
Вам нужно будет определить виртуальный деструктор для всех базовых классов
В дополнение к этому.
Цитата Скотта Мейерса из его книги «Эффективный C ++» ":
Стандарт языка C ++ - необычно ясно по этой теме. когда вы пытаетесь удалить производный класс объект через указатель базового класса а базовый класс имеет не виртуальный деструктор (как и EnemyTarget), результаты не определены
На практике обычно рекомендуется определять класс с помощью виртуального деструктора, если вы думаете, что кто-то может в конечном итоге создать из него производный класс. Я все равно стараюсь сделать так, чтобы все классы имели виртуальный деструктор. Да, это связано с определенными затратами, но цена отказа от того, чтобы сделать его более частым и виртуальным, взвешивает незначительные накладные расходы времени выполнения.
Я предлагаю, делайте его не виртуальным только тогда, когда вы абсолютно уверены, что вы этого хотите, а не полагаться на невиртуальные значения по умолчанию, которые применяют компиляторы. Вы можете не согласиться, однако (в итоге) у меня недавно произошла ужасная утечка памяти в каком-то унаследованном коде, где все, что я сделал, это добавил std :: vector в один из классов, которые существовали в течение нескольких лет. Оказывается, один из его базовых классов не t имеет определенный деструктор (деструктор по умолчанию пустой, не виртуальный!), и поскольку память не выделялась таким образом, прежде чем утечка памяти до этого момента. Многие дни расследования и время потрачено впустую ...
Да, путем наследования от базового класса с помощью виртуального деструктора. В этом случае вы уже платите цену за полиморфный класс (например, vtable).
Ури и Майкл правы - я просто добавлю, что если вас беспокоит то, что вам нужно прикоснуться к двум файлам, чтобы объявить и определить деструктор, совершенно нормально определить минимальный встроенный в заголовке:
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);
}