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
7
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
17 hours ago
3
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
3
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
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
17 hours ago
|
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 15 hours ago
Quark
112
112
asked 17 hours ago
helper
311112
311112
7
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
17 hours ago
3
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
3
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
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
17 hours ago
|
show 8 more comments
7
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
17 hours ago
3
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
3
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
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
17 hours ago
7
7
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
17 hours ago
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
17 hours ago
3
3
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
3
3
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
6
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
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
17 hours ago
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
17 hours ago
|
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.
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
12 hours ago
4
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
12 hours ago
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 17 hours ago
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.
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
12 hours ago
4
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
12 hours ago
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.
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
12 hours ago
4
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
12 hours ago
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 17 hours ago
David Schwartz
135k14140223
135k14140223
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
12 hours ago
4
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
12 hours ago
add a comment |
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
@Rakete1111, A vector of references is not allowed but a vector ofreference_wrapper
does work.
– Vassilis
12 hours ago
4
@Vassilis Jup, but areference_wrapper
is not a reference :)
– Rakete1111
12 hours ago
4
4
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
Note that not all of them work. A vector of references is not allowed.
– Rakete1111
14 hours ago
2
2
@Rakete1111, A vector of references is not allowed but a vector of
reference_wrapper
does work.– Vassilis
12 hours ago
@Rakete1111, A vector of references is not allowed but a vector of
reference_wrapper
does work.– Vassilis
12 hours ago
4
4
@Vassilis Jup, but a
reference_wrapper
is not a reference :)– Rakete1111
12 hours ago
@Vassilis Jup, but a
reference_wrapper
is not a reference :)– Rakete1111
12 hours ago
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
7
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
17 hours ago
3
Also, is Apple polymorphic?
– HolyBlackCat
17 hours ago
3
HolyBlackCat: that's a good question, Apple is not polymorphic. But if it was, we'd definitely want to use a pointer, right?
– helper
17 hours ago
6
@HolyBlackCat: I think so. They sell hardware and software. <g>
– Rudy Velthuis
17 hours ago
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
17 hours ago