Pointer to vector vs vector of pointers vs pointer to vector of pointers

后端 未结 6 1910
你的背包
你的背包 2021-02-03 10:33

Just wondering what you think is the best practice regarding vectors in C++.

If I have a class containing a vector member variable. When should this vector be declared a

相关标签:
6条回答
  • 2021-02-03 10:54

    A pointer to a vector is very rarely useful - a vector is cheap to construct and destruct.

    For elements in the vector, there's no correct answer. How often does the vector change? How much does it cost to copy-construct the elements in the vector? Do other containers have references or pointers to the vector elements?

    As a rule of thumb, I'd go with no pointers until you see or measure that the copying of your classes is expensive. And of course the case you mentioned, where you store various subclasses of a base class in the vector, will require pointers.

    A reference counting smart pointer like boost::shared_ptr will likely be the best choice if your design would otherwise require you to use pointers as vector elements.

    0 讨论(0)
  • 2021-02-03 10:57

    In your example, the vector is created when the object is created, and it is destroyed when the object is destroyed. This is exactly the behavior you get when making the vector a normal member of the class.

    Also, in your current approach, you will run into problems when making copies of your object. By default, a pointer would result in a flat copy, meaning all copies of the object would share the same vector. This is the reason why, if you manually manage resources, you usually need The Big Three.

    A vector of pointers is useful in cases of polymorphic objects, but there are alternatives you should consider:

    1. If the vector owns the objects (that means their lifetime is bounded by that of the vector), you could use a boost::ptr_vector.
    2. If the objects are not owned by the vector, you could either use a vector of boost::shared_ptr, or a vector of boost::ref.
    0 讨论(0)
  • 2021-02-03 11:00

    Definitely the first!

    You use vector for its automatic memory management. Using a raw pointer to a vector means you don't get automatic memory management anymore, which does not make sense.

    As for the value type: all containers basically assume value-like semantics. Again, you'd have to do memory management when using pointers, and it's vector's purpose to do that for you. This is also described in item 79 from the book C++ Coding Standards. If you need to use shared ownership or "weak" links, use the appropriate smart pointer instead.

    0 讨论(0)
  • 2021-02-03 11:00

    Complex answer : it depends.

    if your vector is shared or has a lifecycle different from the class which embeds it, it might be better to keep it as a pointer. If the objects you're referencing have no (or have expensive) copy constructors , then it's better to keep a vector of pointer. In the contrary, if your objects use shallow copy, using vector of objects prevent you from leaking...

    0 讨论(0)
  • 2021-02-03 11:01

    Usually solution 1 is what you want since it’s the simplest in C++: you don’t have to take care of managing the memory, C++ does all that for you (for example you wouldn’t need to provide any destructor then).

    There are specific cases where this doesn’t work (most notably when working with polymorphous objects) but in general this is the only good way.

    Even when working with polymorphous objects or when you need heap allocated objects (for whatever reason) raw pointers are almost never a good idea. Instead, use a smart pointer or container of smart pointers. Modern C++ compilers provide shared_ptr from the upcoming C++ standard. If you’re using a compiler that doesn’t yet have that, you can use the implementation from Boost.

    0 讨论(0)
  • 2021-02-03 11:04

    Deleting all elements in a vector manually is an anti-pattern and violates the RAII idiom in C++. So if you have to store pointers to objects in a vector, better use a 'smart pointer' (for example boost::shared_ptr) to facilitate resource destructions. boost::shared_ptr for example calls delete automatically when the last reference to an object is destroyed.

    There is also no need to allocate MyClass::my_vector using new. A simple solution would be:

    class MyClass {
    
       std::vector<whatever> m_vector;
    };
    

    Assuming whatever is a smart pointer type, there is no extra work to be done. That's it, all resources are automatically destroyed when the lifetime of a MyClass instance ends.

    In many cases you can even use a plain std::vector<MyClass> - that's when the objects in the vector are safe to copy.

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