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?
c++ stl
|
show 8 more comments
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?
c++ stl
9
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
4
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
4
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
2
If it was polymorphic, I'd suggest figure out how to make a copyableunique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.
– HolyBlackCat
Dec 24 '18 at 18:11
|
show 8 more comments
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?
c++ stl
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?
c++ stl
c++ stl
edited Dec 24 '18 at 20:09
user10823628
asked Dec 24 '18 at 18:05
helperhelper
341112
341112
9
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
4
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
4
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
2
If it was polymorphic, I'd suggest figure out how to make a copyableunique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.
– HolyBlackCat
Dec 24 '18 at 18:11
|
show 8 more comments
9
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
4
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
4
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
2
If it was polymorphic, I'd suggest figure out how to make a copyableunique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.
– HolyBlackCat
Dec 24 '18 at 18:11
9
9
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
4
4
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
4
4
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
6
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
2
2
If it was polymorphic, I'd suggest figure out how to make a copyable
unique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.– HolyBlackCat
Dec 24 '18 at 18:11
If it was polymorphic, I'd suggest figure out how to make a copyable
unique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.– HolyBlackCat
Dec 24 '18 at 18:11
|
show 8 more comments
2 Answers
2
active
oldest
votes
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.
add a comment |
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.
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
Dec 24 '18 at 23:03
6
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
Dec 24 '18 at 23:09
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53916524%2fshould-a-stdvector-of-objects-use-pointers-references-or-nothing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
add a comment |
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.
add a comment |
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.
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.
answered Dec 24 '18 at 18:11
community wiki
Zeta
add a comment |
add a comment |
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.
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
Dec 24 '18 at 23:03
6
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
Dec 24 '18 at 23:09
add a comment |
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.
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
Dec 24 '18 at 23:03
6
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
Dec 24 '18 at 23:09
add a comment |
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.
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.
answered Dec 24 '18 at 18:11
David SchwartzDavid Schwartz
136k14142223
136k14142223
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
Dec 24 '18 at 23:03
6
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
Dec 24 '18 at 23:09
add a comment |
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
Dec 24 '18 at 23:03
6
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
Dec 24 '18 at 23:09
6
6
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
Dec 24 '18 at 20:35
3
3
@Rakete1111, A vector of references is not allowed but a vector of
reference_wrapper
does work.– Vassilis
Dec 24 '18 at 23:03
@Rakete1111, A vector of references is not allowed but a vector of
reference_wrapper
does work.– Vassilis
Dec 24 '18 at 23:03
6
6
@Vassilis Jup, but a
reference_wrapper
is not a reference :)– Rakete1111
Dec 24 '18 at 23:09
@Vassilis Jup, but a
reference_wrapper
is not a reference :)– Rakete1111
Dec 24 '18 at 23:09
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53916524%2fshould-a-stdvector-of-objects-use-pointers-references-or-nothing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
9
I'll ask a question back: who shall own the objects you can access by index? The vector? Or will the vector point or reference to another actual owner?
– Zeta
Dec 24 '18 at 18:07
4
Also, is Apple polymorphic?
– HolyBlackCat
Dec 24 '18 at 18:08
4
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
Dec 24 '18 at 18:09
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
Dec 24 '18 at 18:10
2
If it was polymorphic, I'd suggest figure out how to make a copyable
unique_ptr
wrapper (using type erasure) and use that. If it sounds too hard, use pointers.– HolyBlackCat
Dec 24 '18 at 18:11