Destructor (programación informática)

Función llamada al final de la vida útil de un objeto

En programación orientada a objetos , un destructor (a veces abreviado dtor [1] ) es un método que se invoca mecánicamente justo antes de que se libere la memoria del objeto . [2] Puede ocurrir cuando su vida útil está vinculada al ámbito y la ejecución sale del ámbito, cuando está incrustado en otro objeto cuya vida útil 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 sockets, conexiones de base de datos , bloqueos de recursos , etc.) que fueron adquiridos por el objeto durante su vida y/o anular el registro de otras entidades que puedan mantener referencias a él. El uso de destructores es necesario para el proceso de adquisición de recursos es inicialización (RAII).

En la mayoría de los tipos de algoritmos de recolección automática de basura , la liberación de memoria puede ocurrir mucho tiempo después de que el objeto se vuelve inalcanzable, lo que hace que los destructores (llamados finalizadores en este caso) no sean adecuados para la mayoría de los propósitos. En dichos lenguajes, la liberación de recursos se realiza a través de una construcción léxica (como try..finally, "with" de Python o "try-with-resources" de Java), que es el equivalente a RAII, o explícitamente al llamar a una función (equivalente a la eliminación explícita); en particular, muchos lenguajes orientados a objetos utilizan el patrón Dispose .

Sintaxis del destructor

  • C++ : los destructores tienen el mismo nombre que la clase con la que están asociados, pero con un prefijo tilde (~). [2]
  • D : los destructores se declaran con nombre ~this()(mientras que los constructores se declaran con this()).
  • Objeto Pascal : los destructores tienen la palabra clave destructory pueden tener nombres definidos por el usuario, pero en su mayoría son nombrados Destroy.
  • Objective-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 objetos Moose , se llama DEMOLISH.
  • PHP : En PHP 5+, el método destructor tiene el nombre __destruct. No había destructores en versiones anteriores de PHP. [3]
  • Python : hay __del__métodos llamados destructores en la guía del lenguaje Python 2, [4] pero en realidad son finalizadores como se reconoce en Python 3. [5]
  • Rust : el método destructor de rust tiene el nombre drop. [6]
  • Swift : el método destructor tiene el nombre deinit.

En C++

El destructor tiene el mismo nombre que la clase, pero con una tilde (~) antes de él. [2] Por ejemplo, una clase llamada foo tendrá el destructor . Además, los destructores no tienen parámetros ni tipos de retorno. [2] Como se indicó anteriormente, un destructor para un objeto se llama siempre que finaliza la vida útil del objeto. [2] 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 ámbito. Debido a que C++ no tiene recolección de basura, si el objeto se creó con una declaración (dinámicamente en el montón ), entonces se llama a su destructor cuando se aplica el operador a un puntero al objeto. Por lo general, esa operación ocurre dentro de otro destructor, típicamente el destructor de un objeto puntero inteligente .~foo()newdelete

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 se elimine un objeto mediante un puntero a la clase base. Los objetos que se puedan eliminar de esta manera deben heredar un destructor virtual.

Un destructor nunca debería lanzar una excepción. [7]

Los tipos escalares que no son de clase tienen lo que se llama unapseudodestructor al que se puede acceder mediantetypedefargumentos de plantilla o de tipo. Esta construcción permite escribir código sin tener que saber si existe un destructor para un tipo determinado.

int f () { int a = 123 ; usando T = int ; a . ~ T (); devuelve a ; // comportamiento indefinido }              

En versiones anteriores del estándar, se especificaba que los pseudodestructores no tenían efecto; sin embargo, eso se cambió en un informe de defectos para que finalizaran la vida útil del objeto en el que se invocaban. [8]

Ejemplo

#include <cstring> #include <iostream>  clase Foo { público : Foo () : datos_ ( nuevo char [ tamaño de ( "¡Hola, mundo!" )]) { std :: strcpy ( datos_ , "¡Hola, mundo!" ); }          Foo ( const Foo & other ) = delete ; // deshabilitar la construcción de copia Foo & operator = ( const Foo & other ) = delete ; // deshabilitar la asignación             ~ Foo ( void ) { eliminar [] datos_ ; }    privado : amigo std :: ostream & operator << ( std :: ostream & os , const Foo & foo ) { os << foo.data_ ; return os ; }               char * datos_ ; }; int main () { Foo foo ; std :: cout << foo << std :: endl ; }         

Los objetos que no se pueden copiar y/o asignar de forma segura deben ser deshabilitados de dicha semántica declarando sus funciones correspondientes como eliminadas dentro de un nivel de encapsulamiento público. Se puede encontrar una descripción detallada de este método en el popular libro de Scott Meyers , Effective Modern C++ (Ítem 11: "Preferir funciones eliminadas a funciones privadas indefinidas". [9] ).

Clase UML en C# que contiene un constructor y un destructor.

En C con extensiones GCC

El compilador C de GNU Compiler Collection viene con dos extensiones que permiten implementar destructores:

  • El destructoratributo function [10] permite definir funciones destructoras priorizadas a nivel global: cuando main()retorna, estas funciones son llamadas en orden de prioridad antes de que el proceso termine. Véase también: Hacking the art of exploitation . [11]
  • El atributo de variable de limpieza permite adjuntar una función destructora a una variable: la función se llama cuando la variable queda fuera del ámbito.

Xojo

Los destructores en Xojo (REALbasic) pueden adoptar una de dos formas. Cada forma utiliza una declaración de método regular con un nombre especial (sin parámetros ni valor de retorno). La forma más antigua utiliza el mismo nombre que la clase con un prefijo ~ (tilde). La forma más nueva utiliza el nombre Destructor. La forma más nueva es la preferida porque facilita la refactorización de la clase.

Clase Foobar // Forma antigua Subtítulo ~Foobar() Fin del subtítulo // Nueva forma Subdestructor() Fin del subtítuloFin de clase

Véase también

Referencias

  1. ^ "doctor". TheFreeDictionary.com . Consultado el 14 de octubre de 2018 .
  2. ^ abcdeSebesta , Robert W. (2012). ""11.4.2.3 Constructores y destructores"". Conceptos de lenguajes de programación (versión impresa) (10.ª ed.). Boston, MA, EE. UU.: Addison-Wesley. pág. 487. ISBN 978-0-13-139531-2.
  3. ^ Constructores y destructores, de la documentación en línea de PHP
  4. ^ "3. Modelo de datos — Documentación de Python 2.7.18".
  5. ^ "3. Modelo de datos — Documentación de Python 3.10.4".
  6. ^ "Destructores - la referencia de Rust".
  7. ^ GotW #47: Excepciones no detectadas Consultado el 31 de julio de 2011.
  8. ^ Smith, Richard; Voutilainen, Ville. "P0593R6: Creación implícita de objetos para manipulación de objetos de bajo nivel". open-std.org . Consultado el 25 de noviembre de 2022 .
  9. ^ Scott Meyers: C++ moderno y eficaz , O'REILLY, ISBN 9781491903995 
  10. ^ Atributo de la función "destructor" de C
  11. ^ Erickson, Jon (2008). Hackear el arte de la explotación . No Starch Press . ISBN 978-1-59327-144-2.
Obtenido de "https://es.wikipedia.org/w/index.php?title=Destructor_(programación_informática)&oldid=1231202524"