4

I asked a very similar question here but since it is such a fundamental issue I would like to state my (new) question more precicely.

Say I have a very complex class A and each instance of A is stored in multiple containers such as vectors, queues,...

Even in a static setting, meaning that the objects get added to the containers once and will not be deleted nor modified:
Should the containers now contain pointers to the objects or the objects itself?

user695652
  • 4,105
  • 7
  • 40
  • 58

3 Answers3

10

If you need copies of objects - use objects. If you need to share objects or polymorphic behavior is desired - use containers of smart pointers. In case of using smart pointers you will both have automatic object destruction and polymorphic behavior.

For example:

std::vector<std::shared_ptr<MyObject>> v;
auto ptr = std::shared_ptr<MyObject>(new MyObject());
v.push_back(ptr);

If you need to store unique pointers (with no sharing):

std::vector<std::unique_ptr<MyObject>> v;
auto ptr = std::unique_ptr<MyObject>(new MyObject());
v.push_back(std::move(ptr));
Andrew
  • 24,218
  • 13
  • 61
  • 90
  • An example would be useful, in the case of smart pointers as you indicated. – Drise Jun 20 '12 at 14:38
  • Awesome. You can keep my +1 now. :D – Drise Jun 20 '12 at 14:48
  • 2
    @Drise: for efficiency, prefer make_shared() for shared_ptr creation. – WalderFrey Jun 20 '12 at 15:23
  • @WalderFrey: MyObject a(25); and MyObject a = MyObject(25) - are totally the same things. In both case only constructor will be called. The same applies to std::shared_ptr – Andrew Jun 20 '12 at 15:34
  • 1
    @Andrew: No, they're not. And `make_shared` is not related to that, so double no. – Cat Plus Plus Jun 20 '12 at 16:04
  • @Andrew `make_shared` is more efficient (it will allocate a single block instead of two) but not just about efficiency. It's [about exception safety](http://herbsutter.com/gotw/_102/) too: it's a single step, while `shared_ptr(new T)` is two. – R. Martinho Fernandes Jun 20 '12 at 16:09
  • @Andrew: http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati – Mooing Duck Jun 20 '12 at 16:11
  • *"`MyObject a(25);` and `MyObject a = MyObject(25)` are totally the same things."*, Nopes. [Good read](http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati) – Alok Save Jun 20 '12 at 16:11
  • You can actually save quite some overhead on those last two lines by calling [emplace_back](http://en.cppreference.com/w/cpp/container/vector/emplace_back) – KillianDS Jun 20 '12 at 16:28
3

If each instance of A is stored in multiple containers, then you must store (smart) pointers instead of the objects themselves. Otherwise each container would have its own unique copy. Modifying an instance in one container would not affect the others. Even if you're not modifying anything, storing full object copies doesn't say what you mean, i.e., that the instances across the containers are really the same.

Michael Kristofik
  • 34,290
  • 15
  • 75
  • 125
2

If your objects are large, or have high copying costs or are complex to copy, then store smart pointers.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154