delete expression
Destruye objeto(s) previamente asignados por la expresión new y libera el área de memoria obtenida.
Contenidos |
Sintaxis
::
(opcional)
delete
expresión
|
(1) | ||||||||
::
(opcional)
delete[]
expresión
|
(2) | ||||||||
| expression | - |
uno de los siguientes:
|
Explicación
Dado el puntero evaluado a partir de expression (después de posibles conversiones) como ptr .
- un puntero nulo,
- un puntero a un objeto no-array creado por una new-expression , o
- un puntero a un subobjeto base de un objeto no-array creado por una new-expression .
El resultado de la expresión delete siempre tiene tipo void .
Si el objeto que se está eliminando tiene un tipo de clase incompleto en el punto de eliminación, y la clase completa tiene un destructor no trivial o una función de desasignación, el comportamiento es indefinido (hasta C++26) el programa está mal formado (desde C++26) .
Si ptr no es un puntero nulo y la función de desasignación no es un delete destructor (desde C++20) , la expresión delete invoca el destructor (si existe) para el objeto que está siendo destruido, o para cada elemento del array que está siendo destruido (procediendo desde el último elemento al primer elemento del array). El destructor debe ser accesible desde el punto donde aparece la expresión delete.
Después de eso, independientemente de si alguna excepción fue lanzada por cualquier destructor, la expresión delete invoca la función de desasignación : ya sea operator delete (primera versión) o operator delete [ ] (segunda versión) , a menos que la expresión new correspondiente se combinara con otra expresión new (since C++14) .
El nombre de la función de desasignación se
busca
en el ámbito del tipo dinámico del objeto apuntado por
ptr
, lo que significa que las funciones de desasignación específicas de la clase, si están presentes, se encuentran antes que las globales. Si
::
está presente en la expresión delete, solo el espacio de nombres global es examinado por esta búsqueda. En cualquier caso, cualquier declaración que no sea de funciones de desasignación usuales es descartada.
Si se encuentra cualquier función de desasignación, la función a llamar se selecciona de la siguiente manera (ver función de desasignación para una descripción más detallada de estas funciones y sus efectos):
|
(since C++20) |
|
(since C++17) |
- Si las funciones de desasignación encontradas son específicas de la clase, la función de desasignación específica de la clase sin información de tamaño (sin un parámetro de tipo std::size_t ) tiene preferencia sobre la función de desasignación específica de la clase con información de tamaño (con un parámetro de tipo std::size_t ).
|
(desde C++14) |
La función de desasignación seleccionada debe ser accesible desde el punto donde aparece la expresión delete, a menos que la función de desasignación sea seleccionada en el punto de definición del tipo dinámico ’s destructor virtual .
El puntero al bloque de almacenamiento a liberar se pasa a la función de desasignación que fue seleccionada por el proceso anterior como primer argumento. El tamaño del bloque se pasa como el argumento opcional std::size_t . El requisito de alineación se pasa como el argumento opcional std::align_val_t . (desde C++17)
Si ptr es un valor de puntero nulo, no se llaman a los destructores, y la función de desasignación puede o no ser llamada (no está especificado), pero las funciones de desasignación por defecto están garantizadas para no hacer nada cuando se les pasa un puntero nulo.
Si ptr es un puntero a un subobjeto de clase base del objeto que fue asignado con new , el destructor de la clase base debe ser virtual , de lo contrario el comportamiento es indefinido.
Notas
Un puntero a void no puede ser eliminado porque no es un puntero a un tipo de objeto.
|
Debido a que un par de corchetes que sigue a la palabra clave delete siempre se interpreta como la forma de array de una expresión delete, una expresión lambda con una lista de captura vacía inmediatamente después de delete debe estar encerrada entre paréntesis. // delete []{ return new int; }(); // error de análisis delete ([]{ return new int; })(); // OK |
(desde C++11) |
Palabras clave
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 288 | C++98 |
para la primera forma, se comparaba el tipo estático del
operando con su tipo dinámico |
comparar el tipo estático del objeto
a eliminar con su tipo dinámico |
| CWG 353 | C++98 |
no se especificaba si la función de desasignación se invocaría si
el destructor lanzaba una excepción |
siempre se invoca |
| CWG 599 | C++98 |
la primera forma podía aceptar un puntero nulo de
cualquier tipo, incluyendo punteros a función |
excepto punteros a tipos objeto,
se rechazan todos los demás tipos de puntero |
| CWG 1642 | C++98 | expression podría ser un lvalue de puntero | no permitido |
| CWG 2474 | C++98 |
eliminar un puntero a un objeto de un tipo similar pero
diferente resultaba en comportamiento indefinido |
se define correctamente |
| CWG 2624 | C++98 | los punteros obtenidos de operator new [ ] no asignador podían pasarse a delete [ ] | prohibido |
| CWG 2758 | C++98 |
no estaba claro cómo se realizaba el control de acceso para
la función de desasignación y el destructor |
se aclara |