2012-06-23 11 views
6

Estoy leyendo C++ Primer, 3rd Ed (Lippman y Lajoie) y está diciendo que cuando un vector necesita ser reasignado para hacer espacio para más elementos añadidos con push_back(), los elementos son copiados en el nuevo espacio y entonces se llama al destructor sobre los elementos viejos. Estoy confundido acerca de por qué es necesario, ¿por qué los datos no se pueden copiar bit a bit? Supongo que la respuesta tiene que ver con la asignación de memoria dinámica, pero mi línea de razonamiento actual es que incluso si los elementos vectoriales manejan la memoria dinámica, los datos realmente almacenados en los elementos serán punteros, lo que significa que la copia en bit preservará la ubicación que señalan y no presentará ningún problema. Puedo ver cómo volver a ubicar la memoria asignada dinámicamente a la que apuntan los elementos sería un problema, ya que invalidaría los punteros, pero por lo que yo sé, la reubicación del vector no tendría ninguna razón para hacerlo.C++: ¿La reasignación automática de vectores invoca constructores de copia? ¿Por qué?

¿Alguien me puede dar un ejemplo simple de una clase que no debería moverse poco a poco?

+2

El escenario donde el constructor/destructor registra/anula el registro de la dirección de la clase con un objeto principal viene a la mente. –

+1

Me viene a la mente el escenario donde el tipo no es copiable trivialmente. –

+1

ta.spot.is tiene un ejemplo sólido, aunque no llamaría a cada registro de objetos un "padre". Por separado, algunas clases pueden mantener punteros a sus propios miembros de datos, por ejemplo, para modelar algún estado modal, diciendo que algunas operaciones futuras ahora deberían estar afectando a ese miembro específico, o tener un iterador en un vector interno. –

Respuesta

7

Aquí es probablemente la más simple (pero bastante artificiales) ejemplo:

class foo 
{ 
    int i; 
    int* pi; // always points to i 
}; 

Aquí, el constructor de copia sería mantener el invariante que pi puntos a i. El compilador en sí no sería capaz de resolver esta relación por sí mismo, de ahí la necesidad de llamar al constructor de copia.

4

¿Alguien me puede dar un ejemplo simple de una clase que no se debe mover poco a poco?

por la norma, haciendo una clase memcpy en cualquier que no es a POD in C++03 (or trivially copyable in C++11) calificaría. memcpy ing no POD (o no copiables trivialmente) invoca comportamiento indefinido; por lo tanto, se debe usar una copia real (o en C++ 11, mover) constructor debe.

Así std::vector sí se aplica, ya que no es un tipo POD (y en C++ 11, no es trivial copiable).

Cuestiones relacionadas