2012-06-20 10 views
5

Por ejemplo:¿es seguro asignar un contenedor STL?

set<int> s1; 
set<int> s2; 
s1.insert(1); 
s2.insert(2); 
s1 = s2; 

¿Es seguro? Si es así, ¿a dónde llegó el elemento antiguo (y la memoria en la que ocurrieron)?

+2

Esto es lo bueno de utilizar las clases y la sobrecarga del operador. Puede encargarse de eso sin que el usuario tenga que preocuparse por ello. – chris

Respuesta

4

Sí, sus ejemplos son seguros. Pero tenga en cuenta: no asigna s2 a s1, copia s2 a s1. Para obtener más información, consulte esto: set::operator=

+1

¿Ese operador no se conoce comúnmente como * el operador de asignación *? – Flexo

+0

@Flexo Se llama operador de asignación _copy –

+0

@ CaptainObvlious Eso no es lo que llama [C++ - FAQ-lite] (http://www.parashift.com/c++-faq-lite/assignment-operators.html). – Flexo

5

Sí. Los elementos antiguos se destruirán de la forma habitual y se liberará cualquier memoria. (Por supuesto, como siempre, si almacena punteros en el contenedor, solo destruirá el puntero y no liberará lo que apunta)

+2

Afaik Esto es realmente incorrecto. 's1 = s2' solo copia el elemento en s2 y lo coloca en s1. Ambos objetos solo se destruyen una vez que se llega al final del bloque. –

+0

@LukasSchmelzeisen, los elementos antiguos del conjunto al que está copiando. – chris

+1

Para ser claro me refiero a que los elementos antiguos en s1 serán "destruidos" y cualquier memoria utilizada por el contenedor se liberará cuando s2. Los objetos s1 y s2 serán, por supuesto, eliminados al final del bloque. – jcoder

6

Sí, es seguro hacer la tarea. Llama al constructor de copia o al operador de asignación y los elementos más antiguos se borran en s1 y se reemplazan por los elementos de s2.

[Nota:. Si no hubiera habido ningún problema potencial, constructor de copia y asignación habrían sido prohibidos como fstream, ofstream, ifstream]

0

La asignación es seguro.

El operador de asignación destruirá los objetos originalmente contenidos en s1 llamando a su destructor (una operación no operativa trivial para el int en su ejemplo). Si el conjunto también libera la memoria o la conserva como memoria no inicializada para ser utilizada por los elementos añadidos posteriormente, depende de la implementación.

Los nuevos objetos en s1 se copiarán de aquellos en s2, lo que puede llevar un tiempo considerable. En caso de que no desee mantener s2 después de la asignación, mejores enfoques podrían ser intercambiar los dos contenedores o usar la asignación de movimiento de C++ 11.

std::swap(s1, s2); // Backwards-compatible swap 
s1 = std::move(s2); // C++11 rvalue move assignment 

Ambos lo más probable es simplemente intercambiar un único puntero, dejando el contenido que desea tener en S1 y S2 en el resto, que se borra cuando S2 se sale del ámbito.

Cuestiones relacionadas