-3

I want to store elements (let's call it E), but I don't know that I should store them as objects or as pointers pointing to the dynamically allocated objects.

(A,B,C,etc. objects store the reference of the wanted E)

version A:

E e;
store.Add(e); //This time the store contains objects.

In this version the element will be copied to the store, but it's easier to handle. (The objects will be destroyed when the parent object is destroyed)

version B:

E* e = new E();
store.Add(*e); //This time the store contains references.
/*I chose references instead of pointers, 
so I have to use pointers only at allocating and deallocating.*/

In this version there is no copy constr. but I have to delete the objects in the parent object's destructor.

Which is better and why? Which can cause more mistakes and which is more efficient?

Tudvari
  • 2,715
  • 2
  • 14
  • 33

2 Answers2

3

With c++11 an onward you can also just construct them directly inside the container:

std::vector<Widget> widgets;
widgets.emplace_back(/*Parameters to construct a widget*/);

Which is better and why?

That depends on your application. If the container is supposed to own the objects, and they aren't too expensive to copy, value semantics are easier. If they are expansive to copy, but easily movable, the standard containers will move them instead (you of course have to supply the move constructors).

You can also have the best of both worlds, by storing smart pointers instead. That way you'd get polymorphism if that's a requirement.

std::vector<std::unique_ptr<Widget>> widgets;
widgets.push_back(std::make_unique<Widget>(/*Parameters to construct a widget*/));

Which can cause more mistakes and which is more efficient?

The first question depends entirely on your skill as a programmer, and the second cannot be answered with a blanket statement. Programs need to be bench-marked and profiled for efficiency.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
2

It depends on how you're using your store. Storing objects means you will copy them when calling Add, and also when copying the store (among other circumstances): that could have a cost, and can lead to unwanted behaviours.

Pointers may be a good alternative, but you should then prefer managed pointers, like std::unique_ptr, so you won't have to handle deletion.

version C:

auto e = std::unique_ptr<E>(new E());
store.Add(e); //This time the store contains managed pointers.

You can also use std::make_unique if you have C++14 available.

version C bis:

auto e = std::make_unique<E>();
store.Add(e); //This time the store contains managed pointers.

Another option if you need to share the pointed objects can be to use std::shared_ptr, but use it only if need it.

version D:

auto e = std::make_shared<E>();
store.Add(e); //This time the store contains shared managed pointers.
rocambille
  • 15,398
  • 12
  • 50
  • 68