When should I use a vector of objects instead of a vector of pointers?

前端 未结 4 828
野趣味
野趣味 2021-01-04 08:17

I have a collection of polymorphic objects, all derived from my Animal class: Cat, Dog, and MonkeyFish.

My usual mode of operation is to store these objects in a vec

相关标签:
4条回答
  • 2021-01-04 08:23

    In this case, storing a vector of Animal would not work for you, as your animals have different sizes, and you wouldn't be able to store the derived objects in the spaces intended to hold the base class. (And even if they're the same size, you won't get the intended polymorphic effect, as base class methods will be executed - the virtualness of a method doesn't come into play unless you access it through a pointer or reference.)

    If you want to avoid the annoyance of managing the memory yourself, you could consider storing a smart pointer such as a shared_ptr (note that auto_ptr doesn't work with STL containers, according to Max Lybbert), or some variant thereof. That way you can still use your polymorphic class, but it's a little less work for you.

    There's no real hard and fast rules about when to use objects and pointers, although it's worth noting that in some cases, like yours, objects just aren't going to work for you. I tend to use objects whenever nothing precludes it though, although you do have to be concerned about expensive copy operations as you note (although sometimes they can be ameliorated by passing containers by reference).

    0 讨论(0)
  • 2021-01-04 08:25

    Rather than using shared_ptr with standard STL containers, take a look at the Boost Pointer Container Library. It is designed to solve exactly this problem.

    0 讨论(0)
  • 2021-01-04 08:29

    If you ever hear the argument but it'll be so costly to copy them structures all the time when you want to use full objects instead of pointers in a vector, then your 2 main arguments are:

    1. We don't need to worry about the lifetime issues of the pointers, which means no leaks from that particular code (unless, of course, the structures themselves have pointer data, but that's another story).
    2. The data locality of adjacent structures in memory will boost performance in typical usage scenarios, not slow things down like pointer indirection would (relatively speaking).

    The added cost of copying is normally taken when adding stuff to the container, not when using the data - think a bit about it: what do you do most? add items or use them?

    However, when adding polymorphical objects, the pointers are necessary to avoid slicing.

    0 讨论(0)
  • 2021-01-04 08:44

    You should use a vector of objects whenever possible; but in your case it isn't possible.

    Containers of pointers let you avoid the slicing problem. But then you have to call delete on each element, like you are doing. That's annoying but possible. Unfortunately there are cases (when an exception is thrown) where you can't be sure that delete is properly called, and you end up with a memory leak.

    The main solution is to use a smart pointer. Pre-C++11 comes with auto_ptr, but that cannot be used in a standard container. C++11 has std::unique_ptr and std::shared_ptr which are designed to be usable in containers (I prefer std::unique_ptr unless I really need reference counting). If you can't use C++11, the best solution is Boost smart pointers.

    0 讨论(0)
提交回复
热议问题