ATOMP
ATOMP

Reputation: 1489

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

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?

Upvotes: 22

Views: 1519

Answers (2)

Zeta
Zeta

Reputation: 105876

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.

Upvotes: 21

David Schwartz
David Schwartz

Reputation: 182743

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.

Upvotes: 11

Related Questions