Do RValue references delete their bound (non-pointer) object after it is assigned to another pointer?2019 Community Moderator ElectionWhy 'this' is a pointer and not a reference?RValue references, pointers, and copy constructorsrvalue reference with assignement operatorWould you ever mark a C++ RValue reference parameter as constAssigning this pointer to rvalue reference to a pointerOverload resolution between object, rvalue reference, const referenceIs it intended by the C++ standards committee that in C++11 unordered_map destroys what it inserts?Assigning rvalue reference to member variableWhy can I prevent implicit conversions for primitives but not user-defined types?How to use the initializer with an rvalue reference param // Why not possible to initialize a C-style array with another C-style array variable
Time travel short story where dinosaur doesn't taste like chicken
Is it illegal in Germany to take sick leave if you caused your own illness with food?
Playing ONE triplet (not three)
How to make readers know that my work has used a hidden constraint?
What exactly is the purpose of connection links straped between the rocket and the launch pad
Is a lawful good "antagonist" effective?
Can someone explain this Mudra being done by Ramakrishna Paramhansa in Samadhi?
How can I discourage/prevent PCs from using door choke-points?
Confusion with the nameplate of an induction motor
Does Linux have system calls to access all the features of the file systems it supports?
Can the druid cantrip Thorn Whip really defeat a water weird this easily?
Am I not good enough for you?
Decoding assembly instructions in a Game Boy disassembler
Why would a jet engine that runs at temps excess of 2000°C burn when it crashes?
What is the definition of "Natural Selection"?
Rejected in 4th interview round citing insufficient years of experience
Why does Deadpool say "You're welcome, Canada," after shooting Ryan Reynolds in the end credits?
Potentiometer like component
Can "semicircle" be used to refer to a part-circle that is not a exact half-circle?
Format picture and text with TikZ and minipage
What happens with multiple copies of Humility and Glorious Anthem on the battlefield?
Who is our nearest neighbor
What is the difference between "shut" and "close"?
What has been your most complicated TikZ drawing?
Do RValue references delete their bound (non-pointer) object after it is assigned to another pointer?
2019 Community Moderator ElectionWhy 'this' is a pointer and not a reference?RValue references, pointers, and copy constructorsrvalue reference with assignement operatorWould you ever mark a C++ RValue reference parameter as constAssigning this pointer to rvalue reference to a pointerOverload resolution between object, rvalue reference, const referenceIs it intended by the C++ standards committee that in C++11 unordered_map destroys what it inserts?Assigning rvalue reference to member variableWhy can I prevent implicit conversions for primitives but not user-defined types?How to use the initializer with an rvalue reference param // Why not possible to initialize a C-style array with another C-style array variable
Short and simple question:
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
For the same reason, I assume RValue references delete their bound (non-pointer) object after it is assigned to another pointer, meaning the behaviour of the pointer is undefined after. (I'm not sure if this is true)
My question is will a similar code snippet to the following have defined behaviour (if I were to use pNum)? :
//Foo.h
class Foo
public:
Foo(int &&num);
private:
int *pNum;
;
//Foo.cpp
Foo::Foo(int &&num)
:pNum(&num)//Would using/dereferencing pNum in the future cause defined behaviour?
If this is an incorrect method of optimising functions through the use of RValue references as parameters, what is the correct method? e.g. What methods do std functions like emplace or make_shared use?
c++ rvalue-reference
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
Short and simple question:
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
For the same reason, I assume RValue references delete their bound (non-pointer) object after it is assigned to another pointer, meaning the behaviour of the pointer is undefined after. (I'm not sure if this is true)
My question is will a similar code snippet to the following have defined behaviour (if I were to use pNum)? :
//Foo.h
class Foo
public:
Foo(int &&num);
private:
int *pNum;
;
//Foo.cpp
Foo::Foo(int &&num)
:pNum(&num)//Would using/dereferencing pNum in the future cause defined behaviour?
If this is an incorrect method of optimising functions through the use of RValue references as parameters, what is the correct method? e.g. What methods do std functions like emplace or make_shared use?
c++ rvalue-reference
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
Short and simple question:
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
For the same reason, I assume RValue references delete their bound (non-pointer) object after it is assigned to another pointer, meaning the behaviour of the pointer is undefined after. (I'm not sure if this is true)
My question is will a similar code snippet to the following have defined behaviour (if I were to use pNum)? :
//Foo.h
class Foo
public:
Foo(int &&num);
private:
int *pNum;
;
//Foo.cpp
Foo::Foo(int &&num)
:pNum(&num)//Would using/dereferencing pNum in the future cause defined behaviour?
If this is an incorrect method of optimising functions through the use of RValue references as parameters, what is the correct method? e.g. What methods do std functions like emplace or make_shared use?
c++ rvalue-reference
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Short and simple question:
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
For the same reason, I assume RValue references delete their bound (non-pointer) object after it is assigned to another pointer, meaning the behaviour of the pointer is undefined after. (I'm not sure if this is true)
My question is will a similar code snippet to the following have defined behaviour (if I were to use pNum)? :
//Foo.h
class Foo
public:
Foo(int &&num);
private:
int *pNum;
;
//Foo.cpp
Foo::Foo(int &&num)
:pNum(&num)//Would using/dereferencing pNum in the future cause defined behaviour?
If this is an incorrect method of optimising functions through the use of RValue references as parameters, what is the correct method? e.g. What methods do std functions like emplace or make_shared use?
c++ rvalue-reference
c++ rvalue-reference
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited Mar 7 at 10:10
kyle Doidge
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked Mar 7 at 9:52
kyle Doidgekyle Doidge
204
204
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
kyle Doidge is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
You don't. It's a common pattern, but it's not fundamental to how move semantics work. What you need to do, is set things up such that the destruction of the moved-from object won't mess up the moved-to object. In the case of pointers which the destructor is going to free, setting them to nullptr is the obvious choice, but having a separate bool m_hasBeenMovedFrom member set to true would also work, as would setting the pointer to point to a newly allocated object.
The important thing, though, is that rvalue references themselves don't do anything like that. Rvalue references are just a variant of references with slightly different binding semantics from lvalue references. They don't delete things any more than lvalue references do.
In the code you posted, the constructor is receiving an rvalue reference to an object, and storing a pointer to that object. That's dangerous, because you could do something like Foo f(3) (or, since it's a non-explicit one-argument constructor, even just pass 3 to a function expecting a Foo), which would store the pointer to an expiring value. On the other hand, if the passed-in object was guaranteed to outlive Foo everything would be okay, but if you're requiring that, why use an rvalue reference?
Overall, while the code you showed there doesn't by itself have undefined behavior, it is absolutely begging for UB to happen when the class is used. The connotation of an rvalue reference is "this object will be gone soon, so feel free to steal its belongings". An int doesn't have any belongings, so that's not useful... and since it's about to be gone, you don't want to hold a pointer to it.
Incidentally, you will often see standard library functions (and other functions!) of the form template<typename T> someFunc(T && arg). That is not an rvalue reference, but a "forwarding reference", aka a "universal reference", which scads of pages will tell you about (but this is my favorite one). The main thing to remember here is that T && is only going to act like an rvalue reference if it's given an rvalue, and that the function itself needs to be careful not to unconditionally treat it as an rvalue reference.
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doingdelete m_ptr.
– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
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
);
);
kyle Doidge is a new contributor. Be nice, and check out our Code of Conduct.
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%2f55040758%2fdo-rvalue-references-delete-their-bound-non-pointer-object-after-it-is-assigne%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
You don't. It's a common pattern, but it's not fundamental to how move semantics work. What you need to do, is set things up such that the destruction of the moved-from object won't mess up the moved-to object. In the case of pointers which the destructor is going to free, setting them to nullptr is the obvious choice, but having a separate bool m_hasBeenMovedFrom member set to true would also work, as would setting the pointer to point to a newly allocated object.
The important thing, though, is that rvalue references themselves don't do anything like that. Rvalue references are just a variant of references with slightly different binding semantics from lvalue references. They don't delete things any more than lvalue references do.
In the code you posted, the constructor is receiving an rvalue reference to an object, and storing a pointer to that object. That's dangerous, because you could do something like Foo f(3) (or, since it's a non-explicit one-argument constructor, even just pass 3 to a function expecting a Foo), which would store the pointer to an expiring value. On the other hand, if the passed-in object was guaranteed to outlive Foo everything would be okay, but if you're requiring that, why use an rvalue reference?
Overall, while the code you showed there doesn't by itself have undefined behavior, it is absolutely begging for UB to happen when the class is used. The connotation of an rvalue reference is "this object will be gone soon, so feel free to steal its belongings". An int doesn't have any belongings, so that's not useful... and since it's about to be gone, you don't want to hold a pointer to it.
Incidentally, you will often see standard library functions (and other functions!) of the form template<typename T> someFunc(T && arg). That is not an rvalue reference, but a "forwarding reference", aka a "universal reference", which scads of pages will tell you about (but this is my favorite one). The main thing to remember here is that T && is only going to act like an rvalue reference if it's given an rvalue, and that the function itself needs to be careful not to unconditionally treat it as an rvalue reference.
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doingdelete m_ptr.
– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
add a comment |
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
You don't. It's a common pattern, but it's not fundamental to how move semantics work. What you need to do, is set things up such that the destruction of the moved-from object won't mess up the moved-to object. In the case of pointers which the destructor is going to free, setting them to nullptr is the obvious choice, but having a separate bool m_hasBeenMovedFrom member set to true would also work, as would setting the pointer to point to a newly allocated object.
The important thing, though, is that rvalue references themselves don't do anything like that. Rvalue references are just a variant of references with slightly different binding semantics from lvalue references. They don't delete things any more than lvalue references do.
In the code you posted, the constructor is receiving an rvalue reference to an object, and storing a pointer to that object. That's dangerous, because you could do something like Foo f(3) (or, since it's a non-explicit one-argument constructor, even just pass 3 to a function expecting a Foo), which would store the pointer to an expiring value. On the other hand, if the passed-in object was guaranteed to outlive Foo everything would be okay, but if you're requiring that, why use an rvalue reference?
Overall, while the code you showed there doesn't by itself have undefined behavior, it is absolutely begging for UB to happen when the class is used. The connotation of an rvalue reference is "this object will be gone soon, so feel free to steal its belongings". An int doesn't have any belongings, so that's not useful... and since it's about to be gone, you don't want to hold a pointer to it.
Incidentally, you will often see standard library functions (and other functions!) of the form template<typename T> someFunc(T && arg). That is not an rvalue reference, but a "forwarding reference", aka a "universal reference", which scads of pages will tell you about (but this is my favorite one). The main thing to remember here is that T && is only going to act like an rvalue reference if it's given an rvalue, and that the function itself needs to be careful not to unconditionally treat it as an rvalue reference.
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doingdelete m_ptr.
– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
add a comment |
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
You don't. It's a common pattern, but it's not fundamental to how move semantics work. What you need to do, is set things up such that the destruction of the moved-from object won't mess up the moved-to object. In the case of pointers which the destructor is going to free, setting them to nullptr is the obvious choice, but having a separate bool m_hasBeenMovedFrom member set to true would also work, as would setting the pointer to point to a newly allocated object.
The important thing, though, is that rvalue references themselves don't do anything like that. Rvalue references are just a variant of references with slightly different binding semantics from lvalue references. They don't delete things any more than lvalue references do.
In the code you posted, the constructor is receiving an rvalue reference to an object, and storing a pointer to that object. That's dangerous, because you could do something like Foo f(3) (or, since it's a non-explicit one-argument constructor, even just pass 3 to a function expecting a Foo), which would store the pointer to an expiring value. On the other hand, if the passed-in object was guaranteed to outlive Foo everything would be okay, but if you're requiring that, why use an rvalue reference?
Overall, while the code you showed there doesn't by itself have undefined behavior, it is absolutely begging for UB to happen when the class is used. The connotation of an rvalue reference is "this object will be gone soon, so feel free to steal its belongings". An int doesn't have any belongings, so that's not useful... and since it's about to be gone, you don't want to hold a pointer to it.
Incidentally, you will often see standard library functions (and other functions!) of the form template<typename T> someFunc(T && arg). That is not an rvalue reference, but a "forwarding reference", aka a "universal reference", which scads of pages will tell you about (but this is my favorite one). The main thing to remember here is that T && is only going to act like an rvalue reference if it's given an rvalue, and that the function itself needs to be careful not to unconditionally treat it as an rvalue reference.
I am aware that in a move constructor / overloaded assignment you must set RValue references that refer to pointers to nullptr (at the end) in order to avoid deallocation of that resource.
You don't. It's a common pattern, but it's not fundamental to how move semantics work. What you need to do, is set things up such that the destruction of the moved-from object won't mess up the moved-to object. In the case of pointers which the destructor is going to free, setting them to nullptr is the obvious choice, but having a separate bool m_hasBeenMovedFrom member set to true would also work, as would setting the pointer to point to a newly allocated object.
The important thing, though, is that rvalue references themselves don't do anything like that. Rvalue references are just a variant of references with slightly different binding semantics from lvalue references. They don't delete things any more than lvalue references do.
In the code you posted, the constructor is receiving an rvalue reference to an object, and storing a pointer to that object. That's dangerous, because you could do something like Foo f(3) (or, since it's a non-explicit one-argument constructor, even just pass 3 to a function expecting a Foo), which would store the pointer to an expiring value. On the other hand, if the passed-in object was guaranteed to outlive Foo everything would be okay, but if you're requiring that, why use an rvalue reference?
Overall, while the code you showed there doesn't by itself have undefined behavior, it is absolutely begging for UB to happen when the class is used. The connotation of an rvalue reference is "this object will be gone soon, so feel free to steal its belongings". An int doesn't have any belongings, so that's not useful... and since it's about to be gone, you don't want to hold a pointer to it.
Incidentally, you will often see standard library functions (and other functions!) of the form template<typename T> someFunc(T && arg). That is not an rvalue reference, but a "forwarding reference", aka a "universal reference", which scads of pages will tell you about (but this is my favorite one). The main thing to remember here is that T && is only going to act like an rvalue reference if it's given an rvalue, and that the function itself needs to be careful not to unconditionally treat it as an rvalue reference.
answered Mar 7 at 10:17
SneftelSneftel
25k64380
25k64380
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doingdelete m_ptr.
– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
add a comment |
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doingdelete m_ptr.
– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Hey, thanks for the answer, I'm just confused about one thing. I thought raw pointers do not delete the objects they point to upon destruction unless delete is used explicitly. If this is the case, why must we set an RValue reference bound to a pointer to nullptr in a move constructor?
– kyle Doidge
Mar 7 at 10:55
Because in the class's destructor, you're manually doing
delete m_ptr.– Sneftel
Mar 7 at 11:06
Because in the class's destructor, you're manually doing
delete m_ptr.– Sneftel
Mar 7 at 11:06
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
Thanks alot this clears up my confusion
– kyle Doidge
Mar 7 at 11:37
add a comment |
kyle Doidge is a new contributor. Be nice, and check out our Code of Conduct.
kyle Doidge is a new contributor. Be nice, and check out our Code of Conduct.
kyle Doidge is a new contributor. Be nice, and check out our Code of Conduct.
kyle Doidge is a new contributor. Be nice, and check out our Code of Conduct.
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.
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%2f55040758%2fdo-rvalue-references-delete-their-bound-non-pointer-object-after-it-is-assigne%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