-3

What is the difference between std::vector<Class*> and std::vector<Class>? And also, which one is better to work with when it comes to efficiency and to avoid errors?

Deduplicator
  • 41,806
  • 6
  • 61
  • 104
Drako
  • 73
  • 7

3 Answers3

3

vector<Class*> stores a list of pointers to objects, the objects themselves must be allocated separately and because they're pointers you can use polymorphic behaviour, like so:

vector<Foo*> list;
list.push_back( new Bar() ); // class Bar : Foo
list.push_back( somePointerToFoo );
list[0]->someVirtualMethod();

Note that with this approach you must manually delete the objects just as you created them. It might be as simple as this:

for(Foo* f : list) delete f;

...but if your vector stores pointers that were gathered from multiple sources that you're aggregating then you need to determine if list "owns" the pointers or not and delete the objects as appropriate.

vector<Class> stores the actual class value (its fields) inline in the vector itself, which means operations typically involve copying all of the values, which may or may not be intended behavior. You can always create pointers to those elements, but then you're entering into dangerous territory:

vector<Foo> list;
list.push_back( Foo() ); // construct an instance of Foo, which might be copied up to 3 times in this single operation, depending on how smart the compiler+library is
list.push_back( *somePointerToFoo ); // this will dereference and copy this instance of Foo
list[0].someVirtualMethod(); // will not be a vtable call

list.push_back( Bar() ); // forbidden, Bar does not fit into Foo
Dai
  • 110,988
  • 21
  • 188
  • 277
2

What is the difference between vector<Class*> and vector<Class>

vector<Class> stores objects, while vector<Class*> stores pointers to objects. When you push an object into the first kind of vector, it gets copied; the second vector stores the pointer, but the object stays in place.

And also, which one is better to work with when it comes to efficiency and to avoid errors?

Let's start with avoiding errors: if at all possible, use vector<Class> because any resources allocated by the class will be managed automatically by vector. In case of vector<*Class> holding original objects, you would be responsible for calling delete when you are done.

This may not be possible in all cases due to object slicing, so the solution is not universal.

As far as the efficiency goes, vector<*Class> lets you avoid copying, so theoretically it could be more efficient. Even in that case you should prefer smart pointers, such as std::shared_ptr<T> or std::unique_ptr<T>, to built-in pointers, because smart pointers will help you automate resource management.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • One more question. Is this the right way to delete pointers to objects ? for (size_t i=0; i< vec.size();i++) {delete vec[i]; } vec.clear(); – Drako Feb 18 '16 at 01:09
  • @Drako Yes, that would be the correct way. Calling `clear()` is also a good idea, because it helps you avoid accessing a deleted pointer by mistake. – Sergey Kalinichenko Feb 18 '16 at 01:12
  • 2
    It's fine to have a raw pointer in the case that it doesn't control the lifetime of the contained objects. – James Adkison Feb 18 '16 at 01:12
  • 1
    Pointer could be more efficient, but due to the now unpredictable placement of the objects in memory it could turn out to be death on wheels if the objects are small and to be used in a high-speed computation. – user4581301 Feb 18 '16 at 01:15
0

Well, std::vector<T> is a dynamically-resizable array of Ts.

If T is Class*, it stores pointers to Class, if it's Class, then of objects of type Class.

In general, you shouldn't be using raw pointers at all, at least not for owning pointers. Look at smart-pointers.

If you actually want to stor objects of polymorphic class Class or derived, you have to use pointers, or some kind of polymorphic container.

Regarding efficiency, it depends on how easily Class-objects are moved, how big they are, and how often that's done.
In other words, the devil is in the details, and you didn't provide those details.

Deduplicator
  • 41,806
  • 6
  • 61
  • 104