Saltar al contenido

C++ vector de objetos frente a vector de punteros a objetos

Este equipo redactor ha estado mucho tiempo buscando soluciones a tu duda, te brindamos la solución así que nuestro objetivo es que te sea de gran apoyo.

Solución:

Lo que tienes que saber sobre los vectores en c++ es que tienen que usar el operador de copia de la clase de tus objetos para poder ingresarlos en el vector. Si tenía una asignación de memoria en estos objetos que se desasignó automáticamente cuando se llamó al destructor, eso podría explicar sus problemas: su objeto se copió en el vector y luego se destruyó.

Si tiene, en su clase de objeto, un puntero que apunta hacia un búfer asignado, una copia de este objeto apuntará hacia el mismo búfer (si usa el operador de copia predeterminado). Si el destructor desasigna el búfer, cuando se llame al destructor de copia, se desasignará el búfer original, por lo tanto, sus datos ya no estarán disponibles.

Este problema no ocurre si usa punteros, porque controla la vida de sus elementos a través de new/destroy, y las funciones vectoriales solo copian el puntero hacia sus elementos.

Mi pregunta es simple: ¿por qué funcionó el uso de un vector de punteros y cuándo crearía un vector de objetos versus un vector de punteros a esos objetos?

std::vector es como un crudo array asignado con nuevo y reasignado cuando intenta insertar más elementos que su tamaño actual.

Entonces, si contiene A punteros, es como si estuvieras manipulando un array de A*. Cuando necesita cambiar el tamaño (usted push_back() un elemento mientras ya está lleno a su capacidad actual), creará otro A* array y copiar en el array de A* del vector anterior.

si contiene A objetos, entonces es como si estuvieras manipulando un array de Aentonces A debe ser construible por defecto si se producen reasignaciones automáticas. En este caso, la totalidad A los objetos también se copian en otro array.

¿Ver la diferencia? los A objetos en std::vector puede cambiar la dirección si realiza algunas manipulaciones que requieren el cambio de tamaño de la interna array. Ahí es donde la mayoría de los problemas con la contención de objetos en std::vector viene de.

Una forma de usar std::vector sin tener tales problemas es asignar una cantidad suficientemente grande array desde el comienzo. La palabra clave aquí es “capacidad”. los std::vector la capacidad es la verdadero tamaño del búfer de memoria en el que pondrá los objetos. Entonces, para configurar la capacidad, tiene dos opciones:

1) talla tu std::vector en la construcción para construir todo el objeto desde el principio, con el número máximo de objetos, eso llamará a los constructores de cada objeto.

2) una vez que el std::vector está construido (pero no tiene nada en él), usar su reserve() función : el vector asignará un búfer lo suficientemente grande (usted proporciona el tamaño máximo del vector). el vector establecerá la capacidad. Si usted push_back() objetos en este vector o resize() por debajo del límite del tamaño que ha proporcionado en el reserve() llamada, nunca reasignará el búfer interno y sus objetos no cambiarán de ubicación en la memoria, haciendo que los punteros a esos objetos sean siempre válidos (algunas afirmaciones para verificar que el cambio de capacidad nunca ocurra es una práctica excelente).

Si está asignando memoria para los objetos usando new, lo está asignando en el montón. En este caso, debe utilizar punteros. Sin embargo, en C++, la convención generalmente es crear todos los objetos en la pila y pasar copias de esos objetos en lugar de pasar punteros a objetos en el montón.

¿Por qué es esto mejor? Esto se debe a que C++ no tiene recolección de basura, por lo que la memoria de los objetos en el montón no se recuperará a menos que usted especifique delete el objeto. Sin embargo, los objetos en la pila siempre se destruyen cuando dejan el alcance. Si crea objetos en la pila en lugar del montón, minimiza el riesgo de pérdidas de memoria.

Si usa la pila en lugar del montón, necesitará escribir buenos constructores y destructores de copias. Los constructores o destructores de copias mal escritos pueden provocar fugas de memoria o liberaciones dobles.

Si sus objetos son demasiado grandes para copiarlos de manera eficiente, entonces es aceptable usar punteros. Sin embargo, debe usar punteros inteligentes de recuento de referencias (ya sea el auto_ptr de C++0x o uno de los punteros de la biblioteca Boost) para evitar pérdidas de memoria.

Puedes añadir valor a nuestra información participando con tu experiencia en las explicaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *