2010-03-05 30 views
5

Tengo un caso en el que deseo almacenar una lista de recursos en un estándar :: vector. Tal como lo veo, mis opciones son las siguientes:RAII y C++ STL

  1. dar mi recurso un incumplimiento del constructor
  2. tienda como objetos del montón (y se envuelven en un puntero compartida)

Opción 1 hace posible construir recursos no válidos y la opción 2 me obliga a usar el montón.

¿Echas en falta alguna opción aquí?

+1

¿por qué quiere dar los recursos predeterminados ctor? el vector solo requiere copiar ctor. – Naveen

+2

"la opción 2 me obliga a usar el montón"; bueno, el vector también almacenará sus cosas en el montón (a menos que use un asignador personalizado), aunque en la memoria contigua. Por lo tanto, no podrá eludir el uso del montón de una manera u otra. –

+0

encontró que estaba almacenando una referencia en mi recurso, por lo que el problema no era el constructor predeterminado, thx – dirk

Respuesta

7

No necesita un constructor predeterminado para tener un vector de instancias.

La única limitación es que no puede usar vector :: resize con el argumento predeterminado cuando la clase no tiene un constructor predeterminado.

vec.resize(20); // requires default constructor 

pero se puede dar vector :: cambiar el tamaño de un objeto predeterminado:

std::vector<foo> vec; 
vec.resize(20, foo(10)); // give a sample object since foo has not default constructor 
1

Es posible almacenar objetos con Constuctor no trivial en el vector. El almacén de objetos en contenedores stl debe tener una semántica de asignación (copiar el constructor y asignar el operador).

1

Una tercera opción sería usar Boost.PointerContainer. Sin embargo, sus objetos se asignarán individualmente en el montón. Como Johann ha comentado, std :: vector ya hace uso del almacenamiento dinámico para almacenar objetos (contiguamente), por lo que no hay forma de evitar por completo el montón.

A menudo no tiene sentido permitir que los recursos (como mutexes, flujos de E/S, etc.) tengan semántica de copia. Por lo tanto, deben hacerse no copiables haciendo que el constructor de copias y el operador de asignación sean privados. Desafortunadamente, la restricción no copiable hace imposible almacenar recursos directamente como valores dentro de contenedores STL. Por lo tanto, uno debe recurrir a Boost.PointerContainer o contenedores de punteros inteligentes. La sección Motivation de la documentación de Boost.PointerContainer explica por qué prefiere usar una sobre otra.