stringtranslate.com

Duración de la vida del objeto

En la programación orientada a objetos (POO), la duración de un objeto es el período de tiempo entre la creación de un objeto y su destrucción. En algunos contextos de programación, la duración de un objeto coincide con la duración de una variable que representa al objeto. En otros contextos (en los que se accede al objeto por referencia ), la duración de un objeto no está determinada por la duración de una variable. Por ejemplo, la destrucción de la variable puede destruir solo la referencia, no el objeto referenciado.

Terminología

Los aspectos de la duración de un objeto varían entre los lenguajes de programación y dentro de las implementaciones de un lenguaje. Los conceptos básicos son relativamente comunes, pero la terminología varía. Por ejemplo, los conceptos de crear y destruir a veces se denominan construct y destruct y los elementos del lenguaje se denominan constructor (ctor) y destructor (dtor).

Determinismo

La creación de un objeto es generalmente determinista , pero la destrucción varía según el contexto de programación. Algunos contextos permiten la destrucción determinista, pero otros no. En particular, en un entorno de recolección de basura, los objetos se destruyen cuando el recolector de basura lo decide.

La sintaxis para la creación y destrucción varía según el contexto de programación. En muchos contextos, incluidos C++, C# y Java, un objeto se crea mediante una sintaxis especial como . En C++, que proporciona una gestión manual de la memoria , un objeto se destruye mediante la palabra clave . En C# y Java, sin una sintaxis de destrucción explícita, el recolector de elementos no utilizados destruye los objetos no utilizados de forma automática y no determinista.new typename()delete

Un enfoque alternativo y determinista a la destrucción automática es aquel en el que el objeto se destruye cuando el código reduce el número de referencias del objeto a cero.

En un grupo de objetos , donde los objetos pueden crearse con anticipación y reutilizarse, la creación y destrucción aparentes de un objeto pueden no corresponderse con las reales. El grupo proporciona reinicialización para la creación y finalización para la destrucción. Tanto la creación como la destrucción pueden ser no deterministas.

Los objetos con asignación de memoria estática tienen una vida útil que coincide con la ejecución de un programa, pero el orden de creación y destrucción de los diversos objetos estáticos generalmente no es determinista.

Ciclo vital

El ciclo de vida de un objeto se refiere a los eventos que experimenta un objeto, incluyendo la creación y la destrucción.

El ciclo de vida generalmente incluye la administración de la memoria y las operaciones posteriores a la asignación y antes de la desasignación. La creación de objetos generalmente consiste en la asignación e inicialización de memoria , donde la inicialización incluye la asignación de valores a los campos y la ejecución del código de inicialización. La destrucción de objetos generalmente consiste en la finalización (también conocida como limpieza) y la desasignación de memoria (también conocida como liberación). Estos pasos generalmente se realizan en orden como: asignar, inicializar, finalizar, desasignar.

Dependiendo del contexto de programación, estos pasos pueden automatizarse parcial o totalmente y algunos de ellos pueden personalizarse.

La frecuencia de personalización tiende a variar según el paso y el contexto de programación. La inicialización es el paso que se personaliza con más frecuencia. La finalización es común en lenguajes con destrucción determinista, en particular C++, pero rara en lenguajes con recolección de basura. La asignación rara vez se personaliza y la desasignación generalmente no se puede personalizar.

Creación

La forma de crear objetos varía según el contexto de programación. En algunos lenguajes basados ​​en clases, un constructor se encarga de la inicialización. Al igual que otros métodos, un constructor puede sobrecargarse para permitir la creación con un estado inicial diferente.

Destrucción

Generalmente, un objeto se elimina de la memoria cuando ya no se necesita. Sin embargo, si hay suficiente memoria o un programa tiene un tiempo de ejecución corto, es posible que no se destruya el objeto; simplemente se libera la memoria al finalizar el proceso.

En algunos casos, la destrucción de objetos consiste únicamente en liberar memoria, en particular con la recolección de basura, o si el objeto es una estructura de datos simple . En otros casos, la limpieza se realiza antes de la liberación, en particular destruyendo objetos miembros (en la administración manual de memoria) o eliminando referencias del objeto a otros objetos para disminuir los recuentos de referencias (en el recuento de referencias). Esto puede ser automático o se puede llamar a un método de destrucción especial en el objeto.

En lenguajes basados ​​en clases con duración de vida determinista de los objetos, en particular C++, se llama a un destructor cuando se elimina una instancia, antes de que se desasigne la memoria. En C++, los destructores difieren de los constructores en varios aspectos. No se pueden sobrecargar, no deben tener argumentos, no necesitan mantener invariantes de clase y pueden provocar la finalización del programa si lanzan excepciones.

Con la recolección de basura , los objetos pueden destruirse cuando el programa ya no puede acceder a ellos. El recolector de basura llama a un finalizador antes de la liberación de memoria.

La destrucción de un objeto hará que cualquier referencia a él deje de ser válida. Con la gestión manual de la memoria, cualquier referencia existente se convierte en una referencia pendiente . Con la recolección de elementos no utilizados, los objetos solo se destruyen cuando no hay referencias a ellos.

Consistencia

La vida útil de un objeto comienza cuando se completa la asignación y finaliza cuando comienza la desasignación. Por lo tanto, durante la inicialización y la finalización, un objeto está activo, pero puede no estar en un estado consistente. El período entre la finalización de la inicialización y el inicio de la finalización es cuando el objeto está activo y en un estado consistente.

Si falla la creación o la destrucción, el informe de errores (por ejemplo, generando una excepción) puede ser complicado ya que el objeto o los objetos relacionados pueden estar en un estado inconsistente.

Para una variable estática , cuya vida útil coincide con la ejecución del programa, un error de creación o destrucción es problemático ya que la ejecución del programa es antes o después de la ejecución normal.

Programación basada en clases

En la programación basada en clases, la creación de objetos también se conoce como instanciación (creación de una instancia de una clase ). La creación y la destrucción se pueden personalizar mediante un constructor y un destructor y, a veces, con métodos de inicialización y finalización independientes .

En particular, un constructor es un método de clase, ya que no hay ningún objeto (instancia) disponible hasta que se crea el objeto, pero los destructores, inicializadores y finalizadores son métodos de instancia.

Además, los constructores e inicializadores a menudo pueden aceptar argumentos, mientras que los destructores y finalizadores generalmente no lo hacen, ya que a menudo son implícitamente invocables.

Gestión de recursos

En lenguajes con objetos de duración deterministas, la duración de vida puede usarse para complementar la gestión de recursos . Esto se denomina la expresión "Adquisición de recursos es inicialización" (RAII). Los recursos se adquieren durante la inicialización y se liberan durante la finalización. En lenguajes con objetos de duración de vida no deterministas (es decir, recolección de basura), la gestión de la memoria generalmente se mantiene separada de la gestión de otros recursos.

Ejemplos

C++

Una clase C++ se puede declarar con valores predeterminados como:

clase Foo {};  

Cuando se declara en un contexto automático, el objeto se destruye al cierre del bloque en el que se declara.

int bar () { Foo foo (); // foo se destruye aquí }     

Cuando se crea dinámicamente, vive hasta que se destruye explícitamente.

int bar () { Foo * pFoo = new Foo (); eliminar pFoo ; }         

Java

Una clase Java se puede declarar con valores predeterminados como:

clase  Foo {} 

Después de que se crea una instancia (es decir new Foo()), vive hasta que no tiene referencias y el recolector de elementos no utilizados la elimina.

Referencias