c++ - remove - vector c ``
¿Debería siempre llamar a vector clear() al final de la función? (5)
No es necesario, se borrará automáticamente una vez que esté fuera del alcance, es decir, destructor destruirá el objeto contenedor.
Tengo una función simple que usa vectores como este (pseudo código):
void someFunc(void) {
std::vector<std::string> contentVector;
// here are some operations on the vector
// should I call the clear() here or this could be ommited ?
contentVector.clear();
}
¿Debería llamar a clear () o esto podría ser omitido?
No hay absolutamente ninguna necesidad de hacer eso. std::vector
y todos los demás contenedores destruyen automáticamente sus elementos cuando ellos mismos serían destruidos. Eso significa que sus destructores son responsables de esa acción. Entonces, no lo hagas
La belleza de esto es que los contenedores son naturalmente excepcionales seguros [1] :
void someFunc(void) {
std::vector<std::string> contentVector;
// here are some operations on the vector
throw std::runtime_error("I just want to throw!");
contentVector.clear();
}
¿La línea contentVector.clear();
¿ser llamado? No. Pero aún está a salvo porque se garantiza que se contentVector
al destructor de contentVector
.
Del std::vector::~vector [2] :
Destruye el contenedor. Se invocan los destructores de los elementos y se desasigna el almacenamiento utilizado. Tenga en cuenta que si los elementos son punteros, los objetos apuntados no se destruyen.
[1] Sin embargo, aún debe hacer que su excepción de elementos sea segura (pídales que liberen sus recursos de forma adecuada cada vez que se invocan sus destructores).
[2] Ver comentarios a continuación para algunas ideas sobre los documentos de SGI STL .
Puede omitir el uso de la función .clear () porque el destructor del vector se ejecuta una vez que contentVector sale del alcance en ''}''.
Esto desasigna la memoria que almacena los datos del vector.
Si miramos la entrada de cppreference.com para std::vector::~vector dice:
Destruye el contenedor. Se invocan los destructores de los elementos y se desasigna el almacenamiento utilizado. Tenga en cuenta que si los elementos son punteros, los objetos apuntados no se destruyen.
así que no, no tienes que llamar clear .
Si queremos ir al borrador del estándar , tenemos que mirar la sección 23.2.1
generales del contenedor, párrafo 4, que dice:
En las Tablas 96 y 97, X denota una clase de contenedor que contiene objetos de tipo T, a y b denotan valores de tipo X, [...]
y luego mire la Table 96 — Container requirements
que tiene la siguiente entrada de expresión:
(&a)->~X()
y la siguiente nota:
nota: el destructor se aplica a cada elemento de a; toda la memoria está desasignada.
Actualizar
Esto es RAII en acción y como dice Bjarne Stroustrup en ¿Por qué C ++ no proporciona una construcción "por fin"? :
Porque C ++ admite una alternativa que casi siempre es mejor: la técnica de "adquisición de recursos es inicialización" (TC ++ PL3 sección 14.4). La idea básica es representar un recurso por un objeto local, de modo que el destructor del objeto local libere el recurso. De esta forma, el programador no puede olvidarse de liberar el recurso.
Ya que no creo que nadie haya mencionado esto, pero si tu vector era
std::vector<std::string*> vector;
debe liberar la memoria asignada a cada elemento antes de que la función finalice (a menos que haya pasado la propiedad a otro lugar, como una variable global, etc.)
for (auto i : vector) {
delete i;
}