2010-11-29 15 views
13

Duplicar posibles:
Is it OK to use “delete this” to delete the current object?¿Qué pasará si se elimina este en C++

acabo de ver algo de código en el que han hecho delete this; en una función de clase, sé que esto es no es un buen diseño, pero si se define lo que sucederá, digamos que la clase siempre es un puntero desde algún lugar. ¿Siempre se eliminará de la manera correcta?

class A 
{ 
public: 
    void abort() { delete this; } 
}; 

class B 
{ 
    void func() { A* a = new A; a->abort(); } 
}; 
+2

Ver http://stackoverflow.com/questions/447379/what-is-the-use-of-delete-this/447531#447531 – icecrime

+1

Las publicaciones vinculadas están relacionadas, pero no parecen ser duplicados. –

Respuesta

17

Es perfectamente legal en C++ a delete this y en realidad es muy útil para ciertos patrones, como punteros inteligentes. La carga recae en el desarrollador, sin embargo, para asegurarse de que no se invoquen otros métodos o en la pila para this, que accederá a los datos de instancia después de que se produzca la eliminación.

El C++ FAQ Lite tiene una entrada para este, que vale la pena leer

+3

Hay muchas cosas en C++ que son perfectamente legales y aún así son una mala idea. –

0

Como se señaló por un comentarista no hay un comportamiento indefinido si no hay otros miembros son llamados después de eliminar Usted será capaz de seguir a la función si no se accede a otros miembros del objeto.

+2

Siempre que no se use una variable miembro después de la instrucción 'delete', el comportamiento está bien definido. – MartinStettner

1

Sí. Solo tiene que tener cuidado de que no se use ninguna variable de instancia (y ningún método virtual, creo) después de la instrucción delete, ya que el puntero this ya no será válido después del delete.

+0

Eso no es lo único que tiene que tener cuidado. –

1

sí, debería eliminarse normalmente.

Hay algunas ocasiones cuando esto es útil, pero se necesita cuidado adicional para asegurarse de que nunca se acceda al objeto después de eso.

0

En este caso particular, que está bien, pero pensar en lo que pasaría si a es variable automática:

void foo() { 
    A a; 
    a.abort(); // BOOM! 
} 
+0

¿Qué exactamente * sucede * cuando haces esto? – Cameron

+0

Creo que el comportamiento exacto no está definido en el idioma, es decir, es UB. Lo más probable es que la capa del asignador afirme que la dirección no está en su rango válido. Pruébalo :) –

+0

Puedes evitar eso haciendo que el destructor de A esté protegido. Entonces no puede borrar un puntero a A que no sea llamar a su método abort() y no puede crear uno en la pila. – CashCow

2

No es el caso de que delete this; es un mal diseño, y que sin duda no se traduce en un comportamiento indefinido. Hace lo que cabría esperar: borra este objeto. Eso significa que es mejor asegurarse de que no haga nada más con el objeto después de haber llamado al delete this.

Las clases de Microsoft MFC usan ampliamente delete this;, por ejemplo en la clase CWnd (ventana). Cuando una ventana recibe el mensaje WM_DESTROY, la clase contenedora de ventana (que es lo que es el objeto C++) ya no es necesaria, por lo que llama al delete this; (creo que en PostNcDestroy(), en algún lugar así). Es muy claro desde el punto de vista del usuario del framework: solo necesita recordar que hay formas para que el objeto C++ se elimine automáticamente y sea un poco cuidadoso cerca del final de la vida útil de la ventana.

Estoy seguro de que hay muchos otros ejemplos del mundo real donde delete this; es un paradigma útil.

Cuestiones relacionadas