std::move doesn't work when the derived class' destructor is specified












7














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?










share|improve this question
























  • 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); or T a(std::move(b));, check en.cppreference.com/w/cpp/language/move_constructor for more details.
    – Searene
    55 mins ago
















7














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?










share|improve this question
























  • 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); or T a(std::move(b));, check en.cppreference.com/w/cpp/language/move_constructor for more details.
    – Searene
    55 mins ago














7












7








7


5





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?










share|improve this question















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++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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, 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


















  • 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); or T 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












1 Answer
1






active

oldest

votes


















14














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:



enter image description here






share|improve this answer

















  • 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











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
});


}
});














draft saved

draft discarded


















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









14














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:



enter image description here






share|improve this answer

















  • 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
















14














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:



enter image description here






share|improve this answer

















  • 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














14












14








14






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:



enter image description here






share|improve this answer












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:



enter image description here







share|improve this answer












share|improve this answer



share|improve this answer










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














  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

Refactoring coordinates for Minecraft Pi buildings written in Python