Reputation: 1489
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
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
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 Apple
s in it so that the lifetimes are sensibly managed.
Upvotes: 11