ejemplo destructores constructores c++ destructor

c++ - destructores - llamando al destructor explícitamente



constructores y destructores c++ pdf (2)

Me parece que podemos llamar a destructor explícitamente en este caso, ¿podría explicarme por qué?

¿Quieres decir por qué podemos? Porque el lenguaje permite llamadas de destructor explícitas en cualquier objeto. Como dices, por lo general da un comportamiento indefinido ya que la mayoría de los objetos serán destruidos de alguna otra manera, y su comportamiento indefinido es destruir cualquier cosa dos veces (o más generalmente para acceder a ella después de la destrucción). Pero eso solo significa que no debes hacerlo, no que el lenguaje te impida hacerlo.

¿O quieres decir por qué querríamos? Porque así es como destruyes un objeto creado por la colocación nueva.

¿Qué significa esa llamada de destructor en este ejemplo?

Ambos significan lo mismo, y son equivalentes a p->~A() ; ellos llaman al destructor del objeto. El ejemplo demuestra que puede proporcionar argumentos de plantilla aquí si lo desea. No estoy seguro de por qué querrías.

¿Cuáles son los casos que podemos llamar destructores explícitamente además de la eliminación de ubicación?

Creo que puedes llamar a un destructor trivial (uno que no hace nada) cuando quieras; pero no tiene sentido. Creo que destruir una cosa creada con la colocación nueva es la única razón legítima para hacerlo.

Entiendo que en la mayoría de los casos, no deberíamos llamar a un destructor explícitamente. Sin embargo, vi un ejemplo de C ++ 11 Standard N3485 Sección 13.4.5 Argumentos de la plantilla:

Una llamada de destructor explícita para un objeto que tiene un tipo que es una especialización de plantilla de clase puede especificar explícitamente los argumentos de plantilla. Ejemplo:

template<class T> struct A { ~A(); }; void f(A<int>* p, A<int>* q) { p->A<int>::~A(); // OK: destructor call q->A<int>::~A<int>(); // OK: destructor call }

Me parece que podemos llamar a destructor explícitamente en este caso, ¿podría explicarme por qué? ¿Qué significa esa llamada de destructor en este ejemplo? ¿Por qué son razonables?

Otra pregunta:

¿Cuáles son los casos que podemos llamar destructores explícitamente además de cuando estamos implementando la placement delete ?

Gracias.

EDIT: encontré en C ++ FAQ que no deberíamos llamar explícitamente a un destructor en una variable local.


Me parece que podemos llamar a destructor explícitamente en este caso, ¿podría explicarme por qué?

Porque el lenguaje permite que pueda invocar el destructor de cualquier objeto siempre que lo desee (suponiendo que tenga acceso, por ejemplo, no es un destructor privado).

¿Qué significa esa llamada de destructor en este ejemplo?

Simplemente invoca el destructor. Lógicamente, significa que el objeto está destruido y debe considerarse como basura a partir de ese punto y no debe desreferenciarse ni utilizarse. Técnicamente significa que el objeto está en cualquier estado en que el destructor lo deje, lo que para algunos objetos puede ser idéntico a la construcción por defecto (pero nunca, nunca deberías confiar en eso).

¿Por qué son razonables?

Algunas veces necesitas destruir objetos sin liberar su memoria. Esto sucede en muchas clases como variante / cualquiera, varios sistemas de enlace y reflexión de scripts, algunas implementaciones singleton, etc.

Por ejemplo, puede usar std::aligned_storage para asignar un buffer para un objeto y luego usar placement new para construir un objeto en ese buffer. No puede invocar delete en este objeto ya que invocará el destructor y tratará de liberar la memoria que lo respalda. Debe invocar explícitamente el destructor en este caso para destruir correctamente el objeto.

¿Cuáles son los casos que podemos llamar destructores explícitamente además de la eliminación de ubicación?

En realidad, no existe tal cosa como "eliminación de ubicación", que no sea el operador correspondiente a la ubicación nueva (y cualquier llamada a delete invocará implícitamente el destructor, excepto aquellas invocadas por el compilador para la construcción fallida, por ejemplo, su noción de "eliminación de ubicación").

Un ejemplo que di más arriba. Otro ejemplo es std::vector . Puede llamar a funciones miembro como pop_back() . Esto necesita destruir el último elemento en el vector pero no puede usar delete ya que la memoria que respalda el objeto es parte de un buffer más grande que debe ser administrado por separado. Lo mismo ocurre con muchos otros contenedores, como las tablas hash de direccionamiento abierto, deque , etc. Este es un ejemplo de dónde desearía usar la template typename para invocar el destructor de forma explícita.

Es una característica que rara vez va a necesitar el usuario de una biblioteca, pero el implementador de una biblioteca de bajo nivel como STL o incluso algunos frameworks de aplicaciones necesitará usarla aquí y allá.