std::move doesn't work when the derived class' destructor is specified
I was trying to move an instance to another one, as follows:
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
Here is the output:
copy student
As you can see, std::move
didn't work, student
was copied instead of moved, however, if I remove the undergraduate
's destructor, i.e. the following line:
~undergraduate() override = default; // removing this line will make std::move work
The output will become move student
, which means std::move
works. Why? Why didn't std::move
work when the derived class' destructor is specified?
c++
add a comment |
I was trying to move an instance to another one, as follows:
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
Here is the output:
copy student
As you can see, std::move
didn't work, student
was copied instead of moved, however, if I remove the undergraduate
's destructor, i.e. the following line:
~undergraduate() override = default; // removing this line will make std::move work
The output will become move student
, which means std::move
works. Why? Why didn't std::move
work when the derived class' destructor is specified?
c++
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
2
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.
– SergeyA
1 hour ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, likeT a = std::move(b);
orT a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.
– Searene
55 mins ago
add a comment |
I was trying to move an instance to another one, as follows:
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
Here is the output:
copy student
As you can see, std::move
didn't work, student
was copied instead of moved, however, if I remove the undergraduate
's destructor, i.e. the following line:
~undergraduate() override = default; // removing this line will make std::move work
The output will become move student
, which means std::move
works. Why? Why didn't std::move
work when the derived class' destructor is specified?
c++
I was trying to move an instance to another one, as follows:
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
Here is the output:
copy student
As you can see, std::move
didn't work, student
was copied instead of moved, however, if I remove the undergraduate
's destructor, i.e. the following line:
~undergraduate() override = default; // removing this line will make std::move work
The output will become move student
, which means std::move
works. Why? Why didn't std::move
work when the derived class' destructor is specified?
c++
c++
edited 44 mins ago
asked 1 hour ago
Searene
6,5502380111
6,5502380111
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
2
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.
– SergeyA
1 hour ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, likeT a = std::move(b);
orT a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.
– Searene
55 mins ago
add a comment |
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
2
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.
– SergeyA
1 hour ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, likeT a = std::move(b);
orT a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.
– Searene
55 mins ago
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
2
2
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.– SergeyA
1 hour ago
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.– SergeyA
1 hour ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, like
T a = std::move(b);
or T a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.– Searene
55 mins ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, like
T a = std::move(b);
or T a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.– Searene
55 mins ago
add a comment |
1 Answer
1
active
oldest
votes
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
21 mins 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%2f53946915%2fstdmove-doesnt-work-when-the-derived-class-destructor-is-specified%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
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
21 mins ago
add a comment |
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
21 mins ago
add a comment |
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
Specifying a class's destructor inhibits automatic generation of the move constructor and move assignment. You can restore them by using = default
:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant created an excellent table for his Everything You Ever Wanted To Know About Move Semantics (and then some)" presentation:
answered 1 hour ago
Vittorio Romeo
57.1k17153293
57.1k17153293
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
21 mins ago
add a comment |
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
21 mins ago
1
1
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
Thank you for that table! Mind if I save and use intensively?
– YSC
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
1 hour ago
3
3
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
1 hour ago
The easier to remember rule:
=default
or =delete
or implement the 5 special member functions whenever you touch any of them.– Yakk - Adam Nevraumont
21 mins ago
The easier to remember rule:
=default
or =delete
or implement the 5 special member functions whenever you touch any of them.– Yakk - Adam Nevraumont
21 mins 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%2f53946915%2fstdmove-doesnt-work-when-the-derived-class-destructor-is-specified%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
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
1 hour ago
2
std::move
always work. In can't not work, it is a cast in disguise. The question is, why move constructor is not called - which is answered below.– SergeyA
1 hour ago
@JesperJuhl Because move constructor is used here instead of move assignment. Move constructor is called when an object is initialized, like
T a = std::move(b);
orT a(std::move(b));
, check en.cppreference.com/w/cpp/language/move_constructor for more details.– Searene
55 mins ago