c++ - una - ¿Cómo eliminar un objeto construido a través de la colocación de un nuevo operador?
vaciar pila c++ (4)
char * buf = new char[sizeof(T)];
new (buf) T;
T * t = (T *)buf;
//code...
//here I should destruct *t but as it is argument of template and can be
//instantiated via basic types as well (say int) so such code
/*t->~T();*/
//is incorrect (maybe correct? Strange, but it works on VS 2005 for basic types.)
//and this code
/*delete t;*/
//crashes the program.
delete [] buf;
Entonces, ¿cuál es la forma correcta de destruir t
?
PS El código anterior es solo para describir mi problema, y no tengo una relación real con el código que voy a escribir. Así que, por favor, no responda como (¿Por qué usar la ubicación new
lugar de la no práctica? O algo similar)
... instanciado a través de tipos básicos también (digamos
int
) para que dicho código
t->~T();
es incorrecto ...
Incorrecto. Ese código es legal y correcto en el código de la plantilla, incluso si T
puede ser un tipo primitivo.
Estándar de C ++: 5.4.2
5.2.4 Llamada de pseudo destructor [expr.pseudo]
- El uso de un nombre de pseudo-destructor después de un punto
.
o flecha->
operador representa el destructor para el tipo que no es de clase nombrado por nombre-tipo. El resultado solo se utilizará como el operando deloperator ()
llamada de funciónoperator ()
, y el resultado de dicha llamada tiene el tipo void. El único efecto es la evaluación de la expresión de postfix antes del punto o flecha.- El lado izquierdo del operador de punto será de tipo escalar. El lado izquierdo del operador de flecha debe ser de tipo puntero a escalar. Este tipo escalar es el tipo de objeto. El tipo designado por el pseudo destructor nombre será el mismo que el tipo de objeto. Además, los dos nombres de tipo en un pseudodestructor nombre de form
::opt nested-name-specifieropt type-name :: ˜ type-name
designarán el mismo tipo escalar. Las versiones no calificadas de cv del tipo de objeto y del tipo designado por el nombre de pseudo-destructor serán del mismo tipo.
La memoria fue asignada utilizando char*
; que está liberando correctamente utilizando delete[] buf
. Solo necesita llamar al destructor t->~T()
en este caso para t
. No es necesario delete t;
.
La ubicación new
en este caso, se usa solo para construir el objeto, no para la asignación de memoria.
Llama al destructor
T * t = (T *)buf;
t->~T();
luego liberar memoria con delete[] buf
. Llamar a los destructores de manera explícita es exactamente cómo se hace para los objetos creados con una new
ubicación.
Primero destruyes el objeto llamando directamente al destructor:
t->~T();
Luego destruye la memoria llamando a delete[]
en el puntero devuelto por new[]
:
delete []buf;