Ciertamente funciona para objetos creados por new
y cuando la persona que llama de Update
buena información acerca de ese comportamiento. Pero lo evitaría. En su caso, la propiedad claramente está en el mundo, por lo que haría que el mundo lo elimine. El objeto no se crea a sí mismo, creo que tampoco debería eliminarse. Puede ser muy sorprendente si llama a una función "Actualizar" en su objeto, pero de repente ese objeto ya no existe sin que World haga nada por sí mismo (aparte de Quitarlo de su lista, ¡pero en otro marco! La actualización del objeto no se dará cuenta de eso).
Algunas ideas sobre este
- Añadir una lista de referencias a objetos a la Humanidad. Cada objeto en esa lista está pendiente de eliminación. Esta es una técnica común, y se usa en wxWidgets para ventanas de nivel superior que se cerraron, pero aún pueden recibir mensajes. En tiempo de inactividad, cuando se procesan todos los mensajes, se procesa la lista pendiente y se eliminan los objetos. Creo que Qt sigue una técnica similar.
- Comenta al mundo que el objeto quiere ser eliminado. El mundo estará debidamente informado y se encargará de todo lo que se necesite hacer. Algo así como un
deleteObject(Object&)
tal vez.
- Agregue una función
shouldBeDeleted
a cada objeto que devuelve verdadero si el objeto desea ser eliminado por su propietario.
Preferiría la opción 3. El mundo llamaría Actualizar. Y después de eso, busca si el objeto debe eliminarse y puede hacerlo, o si lo desea, recuerda ese hecho al agregar ese objeto a una lista de eliminación pendiente de forma manual.
Es un dolor en el culo cuando no puede estar seguro de cuándo y cuándo no para poder acceder a las funciones y datos del objeto. Por ejemplo, en wxWidgets, hay una clase wxThread que puede operar en dos modos. Uno de estos modos (llamado "desmontable") es que si su función principal regresa (y los recursos de la secuencia deben liberarse), se elimina (para liberar la memoria ocupada por el objeto wxThread) en lugar de esperar al propietario del hilo objeto para llamar a una función de espera o unirse. Sin embargo, esto causa dolor de cabeza severo. Nunca puede llamar a ninguna función porque podría haberse cancelado en cualquier circunstancia, y no puede crearse con nueva. Mucha gente me dijo que no les gusta mucho su comportamiento.
La autodeclaración del objeto contado de referencia está oliendo, imho.Comparemos:
// 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();
};
compararlo con auto-eliminación de objetos refcounted:
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();
};
Creo que la primera es mucho más agradable, y creo que los objetos de referencia contado bien diseñados hacen no no "borrar esto ", porque aumenta el acoplamiento: la clase que utiliza los datos contados de referencia tiene que saber y recordar que los datos se eliminan a sí mismos como un efecto secundario de la disminución del recuento de referencias. Observe cómo "bmp" se convierte posiblemente en un puntero colgante en ~ destructor de Bitmap. Podría decirse que no hacer eso "eliminar esto" es mucho mejor aquí.
respuesta a una pregunta similar "What is the use of delete this"
Tuve un momento difícil para elegir una respuesta aceptada aquí. Estoy escogiendo esto porque describe los problemas que terminé teniendo (cosas distintas de las referencias de tenencia mundiales) y también sugiere shared_ptr que terminó como parte de mi solución. Gracias. –
Otra razón por la que eliminar uno mismo es malo es que impide crear el objeto en la pila en lugar del montón. Además, el acoplamiento a World hace que las pruebas independientes sean imposibles. – walrii