RAII and C++ STL
Asked Answered
P

3

5

I have a case where I wish to store a list of resources in a std::vector. As I see it, my options are as follows:

  1. Give my resource a default constructor
  2. Store them as heap objects (and wrap them in a shared pointer)

Option 1 makes it possible to construct invalid resources and option 2 forces me to use the heap.

Am I missing any options here?

Peeling answered 5/3, 2010 at 7:26 Comment(4)
why do you want to give the resources default ctor? vector requires only copy ctor.Portugal
"option 2 forces me to use the heap" - well, the vector will also store its stuff on the heap (unless you use a custom allocator), although in contiguous memory. So you won't be able to bypass using the heap in one way or another.Dose
found that I was storing a reference in my resource, so the issue was not the default constructor, thxPeeling
@Naveen: The problem with resources is that you often don't want them to have copy semantics.Redvers
B
7

You don't need a default constructor to have a vector of instances.

The only limitation is you can't use vector::resize with the default argument when the class has no default constructor.

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

but you can give vector::resize a default object:

std::vector<foo> vec;
vec.resize(20, foo(10));  // give a sample object since foo has not default constructor
Ballista answered 5/3, 2010 at 7:31 Comment(0)
C
1

You may store objects with non trivial constuctor in vector. The the objects store in stl containers should have assignment semantic (copy constructor and assign operator).

Coffer answered 5/3, 2010 at 7:31 Comment(0)
R
1

A third option would be to use Boost.PointerContainer. However, your objects will still be individually allocated on the heap. As Johann has commented, std::vector already makes use of the heap to store objects (contiguously), so there's no way to completely avoid the heap.

It often doesn't make sense to allow resources (such as mutexes, I/O streams, etc) to have copy semantics. So they must be rendered non-copyable by making the copy constructor and assignment operator private. Unfortunately, the non-copyable restriction makes it impossible to store resources directly as values inside STL containers. One must therefore resort to either Boost.PointerContainer or containers of smart pointers. The Motivation section of the Boost.PointerContainer documentation explains why you'd prefer to use one over the other.

Redvers answered 5/3, 2010 at 14:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.