2012-05-28 20 views
5

duplicados posibles:
C++: Delete this?
Object-Oriented Suicide or delete this; ¿Podría un objeto desasignar su memoria?

estoy aprendiendo C++ mediante la lectura del libro muy bueno C++ Primer y estoy aprendiendo C++ memoria desasigna por la palabra clave delete como C hace con free. Java y Pascal no tienen este mecanismo para liberar explícitamente la memoria. Podría dar lugar a errores en los programas si se ejecutan durante mucho tiempo y se destruyen las variables que se necesitan, por lo que no se debe trivializar.

En resumen, me pregunto si es legal o conveniente, por ejemplo, en C++ para una variable hacer this.delete() y eliminar en sí. Sobre todo escuchamos sobre la liberación de punteros en C y C++ y esto se hace con las nuevas palabras clave free y delete. Pascal también tiene punteros pero Java no. Por lo tanto, en Java no debería ser posible porque no se eliminan explícitamente los objetos, C no tiene objetos, por lo que struct no pudo free la memoria que se asignó, incluso si era técnicamente posible, ya que C no tiene objetos y Pascal tampoco .

Supongo que deja C++ para mi pregunta si es legal que un objeto se elimine con algo como this.delete()?

+0

Doin g así que es posible - 'delete this;' es una sintaxis perfectamente válida en C++ y debe compilar y ejecutar "correctamente". Sin embargo, asume que '* this' está asignado en el montón, que no es necesariamente así. Además, corre el riesgo de dañar aún más la memoria porque una vez liberado, el espacio anteriormente ocupado por '* this' puede ser reutilizado por asignaciones de memoria posteriores. Mala idea. ¡Huir! ¡Huir! –

Respuesta

6

Es perfectamente posible que un objeto haga delete this;.

Sin embargo, después de hacerlo, usar this es un comportamiento indefinido.

lo tanto, si usted es muy cuidadoso con se que se hace después, que está bien y legal para un objeto a "suicidarse" haciendo delete this;

Pero, en realidad no es una buena idea, sobre todo porque significa que su clase solo debe ser instanciada por el nuevo, ya que una asignación en la pila podría causar que el destructor sea llamado dos veces: por la eliminación de esto, y al salir de contexto.

El siguiente ejemplo muestra por qué no es una buena idea:

class A 
{ 
public: 
    ~A() { std::cout << "Destructor"; } 
    void foo() { delete this; } 
}; 

int main() 
{ 
    { 
     A a; 
     a.foo(); // OK, a is deleted 
    } // Going out of context, the destructor is called again => undefined behavior 
    return 0; 
} 
+0

Gracias por la respuesta. Noté que en C++ en comparación con otros idiomas, no es inusual arriesgarse a un "comportamiento no definido". –

+1

@NickRosencrantz: Es * extremadamente * inusual arriesgarse voluntariamente al comportamiento indefinido en el código de producción. – NPE

+3

@NickRosencrantz: en la mayoría de los demás idiomas, el comportamiento indefinido * no existe *. En C++, se debe evitar como la peste, porque es, por definición, poco confiable. No puede confiar en su programa una vez que haya ingresado un comportamiento indefinido. – jalf

5

thises a puntero. La sintaxis correcta sería

delete this; 

Y sí, es posible, pero hace que su objeto y punteros a su objeto inservible.

Ver this para una buena lectura.

En la práctica, usar esta técnica es un olor a código, a menos que esté absolutamente seguro de lo que está haciendo.

+0

Eso es interesante y bueno saberlo. Gracias por la respuesta. –

+0

@NickRosencrantz seguro, ¡me alegra ayudar! –

3

mi pregunta si es legal para un objeto a borrarse a sí mismo con algo como this.delete()?

Técnicamente, es legal que un objeto realice delete this.Sin embargo, hay una serie de advertencias de gran importancia que son explained in the FAQ.

También es importante entender que delete this resuelve un problema técnico muy estrecho. En realidad, no resuelve ninguna pregunta de gran formato sobre la gestión de la memoria y la recolección de basura. Una dirección digna de estudio adicional es the use of smart pointers in C++.

0

Aunque un caso de uso impar sería por ejemplo para un cuadro de diálogo donde el usuario hace clic en Aceptar o lo que sea, esta acción hace que el cuadro de diálogo se elimine pero es legal.

Por supuesto, el puntero this ya no es válido, por lo que no debe intentar usarlo.

0

Es totalmente posible que un objeto desasigne su propia memoria. Sin embargo, es muy poco utilizado, por razones obvias.

El uso más común es para implementar la administración de memoria contada de referencia. Cuando la persona que llama invoca release() y el recuento de referencias llega a cero, el objeto se elimina. Como esto sucede dentro de una variable miembro, usa el puntero this para eliminar la instancia (de la misma forma en que llamaría al delete foo fuera del objeto). Por ejemplo:

int release() 
{ 
    OSAtomicDecrement32(&m_refCount); 
    if (m_refCount <= 0) 
    { 
     delete this; 
    } 
    return m_refCount; 
} 

(Tenga en cuenta que la sintaxis que se menciona no es válida - delete es una palabra clave, no es un método, y this es un puntero.)

Hay varias advertencias a tener en cuenta, sin embargo . Una vez que se ha llamado a esta eliminación, el puntero this ya no es válido, ni ninguno de los miembros de datos. A partir de ese momento, solo se pueden hacer referencias a instancias (por ejemplo, variables locales, métodos y datos estáticos, etc.).

0

Otra forma para el objeto para borrar su memoria está usando algo llamado Adquisición de recursos es de inicialización RAII

Con este método no lo hace new o delete el objeto. Su destructor se llama automáticamente cuando sale de su alcance.

es decir, Usted utilizaría RAII en una función como:

void foo()

{

`Object a;` 

    `int i = a.SomeMethod();` 

    `// a's destructor automatically gets called when the function is out of scope` 

}

Further Reading

Cuestiones relacionadas