2012-02-25 25 views
19

Duplicar posible:
Deleting pointers in a vector¿std :: vector llama al destructor de punteros a los objetos?

sé cuando un std::vector se destruye, se llamará al destructor de cada uno de sus elementos. ¿Llama al destructor de los punteros a los objetos?

vector<myclass*> stuff; 

Cuando las cosas se destruyen, ¿los objetos individuales señalados por los punteros dentro de las cosas se destruyen?

+0

Revisa [boost :: ptr_vector ] (http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/ptr_vector.html) –

Respuesta

30

¿Cómo se supone std::vector saber cómo destruir al cual apunta al objeto? ¿Debería usar delete? delete[]? free? Alguna otra función? ¿Cómo se supone que se sabe que los objetos apuntados se asignan de manera dinámica o que es el Propietario único verdadero y es responsable de destruirlos?

Si el std::vector es el propietario verdadero de los objetos apuntados, utilice std::unique_ptr, potencialmente con un eliminador personalizado para manejar la limpieza de los objetos.

+1

Si 'std :: vector' tiene una constructor que toma una función de destrucción para los elementos que serían excelentes. Sería útil para legacy o C API. Pero, de todos modos, la mejor forma de hacer las cosas es envolver este tipo de recursos con una clase RAII. – wilhelmtell

+1

@wilhelmtell puedes escribir un asignador personalizado para eso :) O dar 'unique_ptr' una función de eliminación personalizada. –

+0

@SethCarnegie sí, me golpeó segundos después de publicar el comentario. me pasa todo el tiempo, hablando antes de pensar. : -S – wilhelmtell

5

No; ¿Qué pasa si almacenaste un puntero a un objeto automático?

vector<T*> v; 
T tinst; 
v.push_back(&tinst); 

Si el vector llama a los destructores de los objetos de los punteros apuntan a, el objeto automática sería destruido dos veces - una vez cuando salió de su alcance, y una vez cuando el vector se fue fuera de alcance. Además, ¿qué ocurre si se supone que no deben desasignarse con delete? No hay forma de que se comporte adecuadamente en cada situación.

Si sus objetos están todos asignados dinámicamente, tiene que iterar manualmente el vector y delete cada puntero si se asignó con new. Como alternativa, puede crear un vector de punteros inteligentes, que se DEALLOCATE los objetos apuntados por los punteros:

vector<shared_ptr<T>> v; 
v.push_back(new T); 
+0

Hm. Creo que la segunda palabra, "porque", es engañosa. La responsabilidad de justificar que no se eliminen los puntos no está en el vector; más bien, el OP debe explicar por qué un contenedor * debe * tratar elementos de tipo puntero de manera diferente. Tal como está, la respuesta podría ser simple, "No". –

+1

@KerrekSB eliminado entonces :) –

15

Como usted ha dicho correctamente a sí mismo, vector hace destructores de llamadas de sus elementos. Entonces, en su ejemplo, el vector hace llamada "destructores de punteros". Sin embargo, debe tener en cuenta que los tipos de punteros no tienen destructores. Solo los tipos de clases pueden tener destructores. Y los punteros no son clases. Por lo tanto, es más correcto decir que std::vector aplica la sintaxis de llamada pseudo-destructor a los objetos de puntero almacenados en el vector. Para los tipos de puntero que dan como resultado no-operación, es decir, no hace nada.

Esto también responde a la segunda parte de su pregunta: si se destruyen los objetos myclass apuntados por los punteros. No, ellos no son destruidos.

Además, parece que de alguna manera cree que "llamar destructores en punteros" (la primera parte de su pregunta) es lo mismo que "destruir los objetos puntiagudos" (la segunda parte de su pregunta). En realidad, estas son dos cosas completamente diferentes que no están relacionadas.

Para crear un enlace de la primera a la última, es decirpara hacer que el vector destruya los objetos puntiagudos, debe construir su vector a partir de algún tipo de "punteros inteligentes", a diferencia de los punteros ordinarios sin procesar myclass *. El vector llamará automáticamente a los destructores de los "punteros inteligentes" y estos destructores, a su vez, destruirán los objetos puntiagudos. Este "enlace" solo puede implementarse explícitamente, dentro del destructor "puntero inteligente", por lo que los punteros crudos ordinarios no pueden ayudarlo aquí.

+0

En realidad, si quiere ser preciso, 'std :: vector' no destruye nada, el asignador hace –

+0

+1 Haha, muy bueno, de manera directa. –

+0

Esta debería ser la respuesta aceptada, ya que muestra por qué los punteros no son un caso especial. –

Cuestiones relacionadas