Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a std::vector of objects use pointers, references, or nothing?

Tags:

Suppose we have some class, say class Apple, and wanted to store a std::vector containing Apple.

Should the vector contain pointers, references, or plain objects?

std::vector<Apple*> vector; // Definitely won't copy the Apple on lookup,      // but I would prefer not to use pointers if I don't have to std::vector<Apple&> vector; // Seems circuitous? std::vector<Apple> vector; // I don't know if this copies the Apple on each lookup 

My goal is to make it so when I call

Apple& a = vector[4]; 

the Apple won't get copied.

I've been using C++ for over a year and I've always worked around this and never understood it. Is there a simple explanation of why one of these three approaches is the best practice?

like image 397
ATOMP Avatar asked Dec 24 '18 18:12

ATOMP


People also ask

When should I use references and when should I use pointers?

Use references when you can, and pointers when you have to. References are usually preferred over pointers whenever you don't need “reseating”. This usually means that references are most useful in a class's public interface. References typically appear on the skin of an object, and pointers on the inside.

Can you use pointers with vectors?

An alternative method uses a pointer to access the vector. w = new std::vector<int>(); The new operator creates a new, empty vector of ints and returns a pointer to that vector. We assign that pointer to the pointer variable w , and use w for the remainder of the code to access the vector we created with new .

Is STD Vector a pointer?

std::vector::dataReturns a direct pointer to the memory array used internally by the vector to store its owned elements.

Do vectors need destructors?

Yes. std::vector and std::string are automatically when they finish out of scope, calling also the destructor of the objects contained (for std::vector ). As said before, std::vector is destroyed when it finish out of scope, calling the destructor of the objects contained.


2 Answers

Use the type T. Remember that operator[] returns a (const) reference, so your Apple& works fine there:

      T& vector<T>::operator[](size_t); const T& vector<T>::operator[](size_t) const; 

That's why you can use vec[3].make_older() to begin with if return_type Apple::make_older(void) exists.

However, keep in mind that there are many methods that invalidate references, so

Apple& reference = vec[3]; vec.push_back(other_apple);  reference.get_eaten(); 

might result in undefined behaviour if push_back reallocated the referenced apple.

like image 127
Zeta Avatar answered Sep 23 '22 18:09

Zeta


Use:

std::vector<Apple> vector; // I don't know if this copies the Apple on each lookup 

While all of them would achieve your goal (a lookup never copies), this is the one that allows the vector to own the Apples in it so that the lifetimes are sensibly managed.

like image 38
David Schwartz Avatar answered Sep 24 '22 18:09

David Schwartz