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 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 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
Dec 27 '18 at 15:06
4
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
Dec 27 '18 at 15:11
@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
Dec 27 '18 at 15:30
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 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 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 Dec 28 '18 at 0:43
Searene
asked Dec 27 '18 at 14:52
SeareneSearene
6,9722383119
6,9722383119
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
Dec 27 '18 at 15:06
4
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
Dec 27 '18 at 15:11
@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
Dec 27 '18 at 15:30
add a comment |
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
Dec 27 '18 at 15:06
4
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
Dec 27 '18 at 15:11
@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
Dec 27 '18 at 15:30
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
Dec 27 '18 at 15:06
You wrote a move constructor but not a matching move assignment operator. Why not?
– Jesper Juhl
Dec 27 '18 at 15:06
4
4
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
Dec 27 '18 at 15:11
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
Dec 27 '18 at 15:11
@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
Dec 27 '18 at 15:30
@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
Dec 27 '18 at 15:30
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:
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
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:
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
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:
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
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 Dec 27 '18 at 14:53
Vittorio RomeoVittorio Romeo
58.1k17158300
58.1k17158300
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
add a comment |
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
The easier to remember rule:=default
or=delete
or implement the 5 special member functions whenever you touch any of them.
– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
3
3
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
Thank you for that table! Mind if I save and use intensively?
– YSC
Dec 27 '18 at 15:06
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
@YSC: I take no credit for the table, it was made by Howard Hinnant.
– Vittorio Romeo
Dec 27 '18 at 15:16
7
7
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
The slides from the host: accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf
– YSC
Dec 27 '18 at 15:18
8
8
The easier to remember rule:
=default
or =delete
or implement the 5 special member functions whenever you touch any of them.– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
The easier to remember rule:
=default
or =delete
or implement the 5 special member functions whenever you touch any of them.– Yakk - Adam Nevraumont
Dec 27 '18 at 16:03
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.
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
Dec 27 '18 at 15:06
4
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
Dec 27 '18 at 15:11
@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
Dec 27 '18 at 15:30