Destructor (programación informática)
En la programación orientada hacia objetos, una destructor (a veces abreviado dtor) es un método que se invoca mecánicamente justo antes de la memoria del objeto es liberado. Puede ocurrir cuando su vida está ligada al alcance y la ejecución deja el alcance, cuando está incrustada en otro objeto cuya vida termina, o cuando se asignó dinámicamente y se libera explícitamente. Su propósito principal es liberar los recursos (asignaciones de memoria, archivos abiertos o tomas de corriente, conexiones de bases de datos, candados de recursos, etc.) que fueron adquiridos por el objeto durante su vida y/o desregistrar de otras entidades que puedan mantener referencias a él. Se necesita el uso de destructores para el proceso de adquisición de recursos Es inicialización (RAII).
Con la mayoría de tipos de algoritmos automáticos de recolección de basura, la liberación de memoria puede pasar mucho tiempo después de que el objeto se vuelva inalcanzable, haciendo que los destructores (llamados finalizadores en este caso) no sean adecuados para la mayoría de los propósitos. En tales idiomas, la liberación de recursos se realiza ya sea a través de un constructo lexical (como tratar..finalmente, el "con" o el "try-with-resources") de Python, que es el equivalente a la RAII, o explícitamente llamando a una función (equivalente a la eliminación explícita); en particular, muchos lenguajes orientados a objetos utilizan el patrón Dispose.
Sintaxis destructor
- C++: los destructores tienen el mismo nombre que la clase con la que están asociados, pero con un prefijo de inclinación (~).
- D: los destructores son declarados con nombre
~this()
(como constructores son declarados conthis()
). - Objeto Pascal: los destructores tienen la palabra clave
destructor
y puede tener nombres definidos por el usuario, pero son mayormente nombradosDestroy
. - Objetivo-C: el método destructor tiene el nombre
dealloc
. - Perl: el método destructor tiene el nombre
DESTROY
; en la extensión del sistema de objeto Moose, se llamaDEMOLISH
. - PHP: En PHP 5+, el método de destructor tiene el nombre
__destruct
. No había destructores en versiones anteriores de PHP. - Python:
__del__
métodos llamados destructores por el Python 2 guía de idiomas, pero en realidad son finalizadores como se reconoce en Python 3. - Rust: el método destructor para el óxido tiene el nombre
drop
- Swift: el método de destructor tiene el nombre
deinit
.
En C++
El destructor tiene el mismo nombre que la clase, pero con una tilde (~) delante. Por ejemplo, una clase llamada foo tendrá el destructor ~foo()
. Además, los destructores no tienen parámetros ni tipos de retorno. Como se indicó anteriormente, se llama a un destructor de un objeto cada vez que finaliza la vida útil del objeto. Si el objeto se creó como una variable automática, su vida útil finaliza y el destructor se llama automáticamente cuando el objeto sale del alcance. Debido a que C++ no tiene recolección de basura, si el objeto se creó con una nueva declaración (dinámicamente en el montón), entonces se llama a su destructor cuando se aplica el operador de eliminación a un puntero al objeto. Normalmente esa operación ocurre dentro de otro destructor, típicamente el destructor de un objeto de puntero inteligente.
En las jerarquías de herencia, la declaración de un destructor virtual en la clase base garantiza que los destructores de las clases derivadas se invoquen correctamente cuando un objeto se elimina a través de un puntero a clase base. Los objetos que puedan eliminarse de esta manera deben heredar un destructor virtual.
Un destructor nunca debería generar una excepción.
Los tipos escalares sin clase tienen lo que se llama un pseudo- destructor al que se puede acceder mediante typedef
o argumentos de plantilla. Esta construcción permite escribir código sin tener que saber si existe un destructor para un tipo determinado.
int f() {} int a = 123; utilizando T = int; a.~T(); Regreso a; // comportamiento indefinido}
En versiones anteriores del estándar, se especificaba que los pseudodestructores no tenían ningún efecto, sin embargo, eso se cambió en un informe de defectos para que finalizaran la vida útil del objeto al que se invocan.
Ejemplo
#include ■cstring#include ■iostreamclase Foo {}público: Foo(): data_()nuevo char[tamaño()"¡Hola, Mundo!")] {} std::strcpy()data_, "¡Hola, Mundo!"); } Foo()const Foo" otros) = Borrar; / / / Construcción de copia deshabilitada Foo" operador=()const Foo" otros) = Borrar; // asignación deshabilitada ~Foo()vacío) {} Borrar[] data_; }privado: amigo std::ostream" operadorc) c)()std::ostream" Os, const Foo" Foo) {} Os c) c) Foo.data_; Regreso Os; } char* data_;};int principal() {} Foo Foo; std::cout c) c) Foo c) c) std::endl;}
Los objetos que no se pueden copiar y/o asignar de forma segura deben desactivarse de dicha semántica declarando que sus funciones correspondientes se eliminan dentro de un nivel de encapsulación pública. Puede encontrar una descripción detallada de este método en Scott Meyers' libro popular, C++ moderno efectivo (Ítem 11: "Preferir funciones eliminadas a funciones privadas no definidas.").

En C con extensiones GCC
El compilador C de la GNU Compiler Collection viene con 2 extensiones que permiten implementar destructores:
- El
destructor
función atributo permite definir las funciones de destructor priorizado global: cuandomain()
devuelve, estas funciones se llaman en orden prioritario antes de que el proceso termine. Véase también: Hacking el arte de la explotación. - El atributo variable de limpieza permite adjuntar una función de destructor a una variable: la función se llama cuando la variable sale del alcance.
Xojo
Los destructores en Xojo (REALbasic) pueden tener dos formas. Cada formulario utiliza una declaración de método normal con un nombre especial (sin parámetros ni valor de retorno). La forma anterior usa el mismo nombre que la Clase con un prefijo ~ (tilde). El formulario más nuevo utiliza el nombre Destructor
. Se prefiere la forma más nueva porque facilita la refactorización de la clase.
Clase Foobar // Forma antigua Sub ~Foobar() End Sub // Nueva forma Subdestructor() End Sub Clase final