Это определенно работает для объектов, созданных new
и когда вызывающий Update
должным образом проинформирован об этом поведении. Но я бы этого не сделал. В вашем случае право собственности явно принадлежит миру, поэтому я бы заставил мир удалить его. Объект не создает себя, думаю, он тоже не должен удаляться. Это может быть очень удивительно, если вы вызываете функцию «Обновить» для своего объекта, но затем внезапно этот объект больше не существует, а World ничего не делает из себя (кроме удаления его из своего списка - но в другом кадре! Обновление по объекту этого не заметит).
Некоторые идеи по этому поводу
- Добавьте список ссылок на объекты в World. Каждый объект в этом списке ожидает удаления. Это распространенный метод, который используется в wxWidgets для окон верхнего уровня, которые были закрыты, но все еще могут получать сообщения. Во время простоя, когда все сообщения обрабатываются, обрабатывается список ожидающих, а объекты удаляются. Я считаю, что Qt следует аналогичной технике.
- Скажите миру, что объект хочет быть удален. Мир будет должным образом проинформирован и позаботится обо всем, что необходимо сделать. Может быть, что-то вроде
deleteObject(Object&)
.
- Добавьте
shouldBeDeleted
функцию к каждому объекту, которая возвращает истину, если объект желает удалить его владельцем.
Я бы предпочел вариант 3. Мир назовет Обновление. И после этого он смотрит, следует ли удалить объект, и может это сделать - или, если хочет, запоминает этот факт, вручную добавляя этот объект в список ожидающих удаления.
Это головная боль, когда вы не можете быть уверены, когда и когда не сможете получить доступ к функциям и данным объекта. Например, в wxWidgets есть класс wxThread, который может работать в двух режимах. Один из этих режимов (называемый «отсоединяемым») заключается в том, что если его основная функция возвращается (и ресурсы потока должны быть освобождены), он удаляет себя (чтобы освободить память, занятую объектом wxThread) вместо ожидания владельца потока. объект для вызова функции ожидания или соединения. Однако это вызывает сильную головную боль. Вы никогда не можете вызывать какие-либо функции на нем, потому что он мог быть прерван при любых обстоятельствах, и вы не можете создать его не с помощью new. Некоторые люди сказали мне, что им очень не нравится такое поведение.
Самостоятельное удаление объекта с подсчетом ссылок пахнет, имхо. Сравним:
// bitmap owns the data. Bitmap keeps a pointer to BitmapData, which
// is shared by multiple Bitmap instances.
class Bitmap {
~Bitmap() {
if(bmp->dec_refcount() == 0) {
// count drops to zero => remove
// ref-counted object.
delete bmp;
}
}
BitmapData *bmp;
};
class BitmapData {
int dec_refcount();
int inc_refcount();
};
Сравните это с самоудалением пересчитываемых объектов:
class Bitmap {
~Bitmap() {
bmp->dec_refcount();
}
BitmapData *bmp;
};
class BitmapData {
int dec_refcount() {
int newCount = --count;
if(newCount == 0) {
delete this;
}
return newCount;
}
int inc_refcount();
};
Я думаю, что первый вариант намного лучше, и я считаю, что хорошо спроектированные объекты с подсчетом ссылок не "удаляют это", потому что это увеличивает связь: класс, использующий данные с подсчетом ссылок, должен знать и помнить о что данные удаляются как побочный эффект уменьшения счетчика ссылок. Обратите внимание, как "bmp" становится, возможно, висящим указателем в деструкторе ~ Bitmap. Возможно, здесь гораздо лучше не делать «удалить это».
Ответьте на аналогичный вопрос "Какая польза от удаления этого"
person
Johannes Schaub - litb
schedule
06.02.2009