Robo
Robo

Reputation: 311

std::vector, constructors, objects

The folowing constructor

 std::vector<Object> objects(n);

creates n objects calling the default constructor, i.e. something like that:

std::vector <Object> objects;
for (unsigned int i = 0; i < n; i++) objects.push_back(o);

Is this procedure also valid for dynamically allocated objects? Does the construction

std::vector<Object *> objects(n);

represent this functionality?

std::vector <Object*> objects;
for (unsigned int i = 0; i < n; i++) objects.push_back(new Object());

If not, is there a way how to arrange it?

Upvotes: 1

Views: 6416

Answers (4)

zwol
zwol

Reputation: 140748

Your final code example has the right general idea, but tread carefully: vector will not manage the allocations for you if you do that! objects.clear() will leak memory, for instance.

You probably want to use std::vector<some_smart_ptr<Object> > instead, but choosing the right smart pointer class requires care and attention to (for instance) what happens when you copy elements from one vector to another. boost::shared_ptr is a safe choice, but may have unnecessary overhead for your use case. boost::ptr_vector may be better.

Upvotes: 0

James McNellis
James McNellis

Reputation: 355187

std::vector<Object> objects(n); 

The behavior of this depends on which version of the C++ Standard your Standard Library implementation implements:

  • In C++03, this creates one default constructed Object and then copy constructs that object n times.

  • In C++0x, this default constructs n Objects.

The difference shouldn't usually matter, but it's good to know.


std::vector<Object *> objects(n);  

This creates a vector with n null Object*s in it. Since Object* is not a class type and does not have a constructor, the newly inserted objects are value initialized, which for pointers means they are set to NULL.

If you want to dynamically create new objects and then store pointers to them in the container, you need to call new yourself. Note that you should not be storing raw pointers in a standard library container if the container owns the pointed-to objects. Doing so is not exception safe.

You should be using a smart pointer like shared_ptr or unique_ptr instead (note: the auto_ptr smart pointer cannot be stored in containers due to its unusual copy semantics, thus shared_ptr or unique_ptr should be used).

In any case, to insert pointers to n distinct, dynamically allocated objects into the container, you need to call new n times to create those n objects. There's nothing wrong with your for loop solution.

Upvotes: 6

trojanfoe
trojanfoe

Reputation: 122401

No, the vector won't be automatically created with pointers to Object instances. You will have to perform the for loop you have written in order to populate it correctly.

You will also need to delete each of these objects when you have finished with them too.

Upvotes: 0

CB Bailey
CB Bailey

Reputation: 792497

The folowing constructor

std::vector<Object> objects(n);

creates n objects calling the default constructor

Yes, but the default constructor is used only to construct the second optional parameter to the constructor of vector, the n objects in the vector are constructed by copying this parameter. [C++03 answer]

If you did something like:

std::vector<Object*> objects(n, new Object());

you would dynamically allocate one object and have n pointers to that object in your vector which is probably not what you want.

It is almost always a bad idea to use a container of pointers if that container is supposed to own the dynamically allocated objects. You should consider something like boost::ptr_vector, or if that is not possible a container of smart pointers (not std::auto_ptr, though).

Upvotes: 2

Related Questions