2011-05-29 19 views
20

Duplicar posibles:
STL containers element destruction orderOrden de destrucción de elementos de un std :: vector

¿Hay una garantía de los elementos de una std::vector serían destruidos desde el último al primero?

+0

Supongo que eso depende de si la garantía también se aplica a las matrices en bruto, ya que std :: vector imita las matrices. Pero no sé lo que dice el estándar sobre eso. – Klaim

+0

@Klaim: 'std :: vector' imita las matrices solo con la sintaxis' op [] '; eso no dice nada sobre la garantía de por vida de ningún elemento. –

+0

Buena captura @Kirill. –

Respuesta

15

2003: 5.3.5/6 dice sobre delete[]:

siendo borrado El delete-expresión invocará el destructor (si lo hay) para el objeto o los elementos de la matriz. En el caso de una matriz, los elementos serán destruidos en orden decreciente de dirección de (es decir, en el orden inverso de la finalización de su constructor; ver 12.6.2).

Así que si su asignador de std::vector objeto utiliza delete[] entonces, sí, se ve obligada a destruir elementos en orden inverso.

Sin embargo, no hay garantía de que su std::vector funcione de esta manera (y, de hecho, es muy probable que no lo haga), y no puedo encontrar ninguna cita específica del contenedor.

Realmente, creo que todo se reduce a su asignador y 2003: 20.1.5 (que se enumeran los requisitos colocados sobre asignadores) no parece decir nada al respecto.

+0

cualquier idea sobre si sale del alcance y se llama vector :: ~ vector()? – Jordan

+0

@Yoel: ¿Eh? ¿Qué importa cómo se invoca la destrucción de 'std :: vector'? Estamos hablando de la destrucción de sus elementos. –

+4

Es casi seguro que 'std :: vector' NO usará' delete [] ', ya que una implementación razonable quiere espacio adicional asignado pero no inicializado, para el cual los constructores no se han ejecutado (y por lo tanto los destructores no deberían ejecutarse). –

3

Ellos garantías estándar esto para una matriz prima, pero no puedo encontrar nada que garantice que para los contenedores.

De [expr.delete] (nueva redacción para C++ 0x):

Si el valor del operando de la eliminación-expresión no es un valor de puntero nulo, el borrado expresión se invocar el destructor (si hay alguno) para el objeto o los elementos de la matriz que se eliminan. En el caso de una matriz , los elementos serán destruidos en orden decreciente de dirección (es decir, en el orden inverso de la finalización de su constructor; ver 12.6.2).

std::vector (y, de hecho, todos los contenedores en la biblioteca estándar, posiblemente con exclusión std::array) no utilizan delete[] para destruir los elementos (utilizan allocator_traits<allocator_type>::destroy en cada elemento de forma individual), por lo que la garantía anterior no se aplica. Y no puedo encontrar restricciones en el std::vector en particular o contenedores en general, sobre el orden de eliminación. Para algunos contenedores, tal garantía sería muy caro (por ejemplo std::forward_list no puede iterar los elementos en sentido inverso para eliminarlos, y std::map no recuerda el orden en el que se añadieron pares).

De [container.requirements.general] (C++ 0x redacción):

Para los componentes a ff reflejada por esta subcláusula que declarar una allocator_type, los objetos almacenados en estas componentes se construye utilizando los allocator_traits :: función y construir destruido usando la función allocator_traits :: destroy (20.6.8.2).

3

No, no son garantías para arrays, donde se construyen todos los elementos se orden y destruido en el orden inverso. Esto es algo consistente con la forma en que se manejan los objetos globales.

miembros para contenedores, por otro lado, pueden ser construidos y destruidos en cualquier orden usando por ejemplo insert y erase funciones miembro. Para ser algo consistente y destruir los elementos en el orden inverso de construcción, esto requeriría que los contenedores guarden algún tipo de registro sobre estos cambios. ¡Obviamente esto sería costoso!

La mejor apuesta es que el destructor de contenedor llama al clear(), que se define como erase(begin(), end()), pero no encuentro ningún requisito para eso tampoco. La norma solo dice "complejidad lineal" en la tabla 65.

+1

No sé por qué esto fue votado negativamente, ya que el cobrador anónimo cobarde no pudo dejar un comentario. +1 de mi parte –

Cuestiones relacionadas