C++ copy constructor called at return












9















error: use of deleted function 'A::A(const A&)'
return tmp;
^~~


Why is the copy constructor called only when there is a virtual destructor in A? How to avoid this?



struct B {};

struct A{
std::unique_ptr<B> x;
virtual ~A() = default;
};

A f() {
A tmp;
return tmp;
}









share|improve this question









New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • see: In which situations is the C++ copy constructor called?

    – kmdreko
    5 hours ago






  • 3





    C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

    – Everyone
    5 hours ago
















9















error: use of deleted function 'A::A(const A&)'
return tmp;
^~~


Why is the copy constructor called only when there is a virtual destructor in A? How to avoid this?



struct B {};

struct A{
std::unique_ptr<B> x;
virtual ~A() = default;
};

A f() {
A tmp;
return tmp;
}









share|improve this question









New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • see: In which situations is the C++ copy constructor called?

    – kmdreko
    5 hours ago






  • 3





    C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

    – Everyone
    5 hours ago














9












9








9


1






error: use of deleted function 'A::A(const A&)'
return tmp;
^~~


Why is the copy constructor called only when there is a virtual destructor in A? How to avoid this?



struct B {};

struct A{
std::unique_ptr<B> x;
virtual ~A() = default;
};

A f() {
A tmp;
return tmp;
}









share|improve this question









New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












error: use of deleted function 'A::A(const A&)'
return tmp;
^~~


Why is the copy constructor called only when there is a virtual destructor in A? How to avoid this?



struct B {};

struct A{
std::unique_ptr<B> x;
virtual ~A() = default;
};

A f() {
A tmp;
return tmp;
}






c++






share|improve this question









New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 4 hours ago







Sobuch













New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 5 hours ago









SobuchSobuch

485




485




New contributor




Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Sobuch is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.













  • see: In which situations is the C++ copy constructor called?

    – kmdreko
    5 hours ago






  • 3





    C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

    – Everyone
    5 hours ago



















  • see: In which situations is the C++ copy constructor called?

    – kmdreko
    5 hours ago






  • 3





    C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

    – Everyone
    5 hours ago

















see: In which situations is the C++ copy constructor called?

– kmdreko
5 hours ago





see: In which situations is the C++ copy constructor called?

– kmdreko
5 hours ago




3




3





C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

– Everyone
5 hours ago





C++ handles objects different than C#/Java. When an instance goes out of scope (tmp here) its destructor must be called. Therefore, when you return tmp then you're asking it to make a copy of tmp to be return to whomever calls the function. Once copied, tmp will be destroyed and its copy will be available for use.

– Everyone
5 hours ago












1 Answer
1






active

oldest

votes


















20














virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.



There are two ways you can fix this. You can add a move constructor like



struct A{
std::unique_ptr<B> x;

A() = default; // you have to add this since the move constructor was added
A(A&&) = default; // defaulted move
virtual ~A() = default;
};


or you can create a base class that has the virtual destructor and inherit from that like



struct C {
virtual ~C() = default;
};

struct A : C {
std::unique_ptr<B> x;
};





share|improve this answer





















  • 6





    Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

    – 0x5453
    5 hours ago






  • 2





    @0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

    – NathanOliver
    5 hours ago






  • 2





    @Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

    – eerorika
    5 hours ago








  • 3





    @Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

    – Angew
    5 hours ago






  • 3





    @Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

    – NathanOliver
    5 hours 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
});


}
});






Sobuch is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55288708%2fc-copy-constructor-called-at-return%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









20














virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.



There are two ways you can fix this. You can add a move constructor like



struct A{
std::unique_ptr<B> x;

A() = default; // you have to add this since the move constructor was added
A(A&&) = default; // defaulted move
virtual ~A() = default;
};


or you can create a base class that has the virtual destructor and inherit from that like



struct C {
virtual ~C() = default;
};

struct A : C {
std::unique_ptr<B> x;
};





share|improve this answer





















  • 6





    Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

    – 0x5453
    5 hours ago






  • 2





    @0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

    – NathanOliver
    5 hours ago






  • 2





    @Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

    – eerorika
    5 hours ago








  • 3





    @Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

    – Angew
    5 hours ago






  • 3





    @Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

    – NathanOliver
    5 hours ago


















20














virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.



There are two ways you can fix this. You can add a move constructor like



struct A{
std::unique_ptr<B> x;

A() = default; // you have to add this since the move constructor was added
A(A&&) = default; // defaulted move
virtual ~A() = default;
};


or you can create a base class that has the virtual destructor and inherit from that like



struct C {
virtual ~C() = default;
};

struct A : C {
std::unique_ptr<B> x;
};





share|improve this answer





















  • 6





    Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

    – 0x5453
    5 hours ago






  • 2





    @0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

    – NathanOliver
    5 hours ago






  • 2





    @Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

    – eerorika
    5 hours ago








  • 3





    @Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

    – Angew
    5 hours ago






  • 3





    @Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

    – NathanOliver
    5 hours ago
















20












20








20







virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.



There are two ways you can fix this. You can add a move constructor like



struct A{
std::unique_ptr<B> x;

A() = default; // you have to add this since the move constructor was added
A(A&&) = default; // defaulted move
virtual ~A() = default;
};


or you can create a base class that has the virtual destructor and inherit from that like



struct C {
virtual ~C() = default;
};

struct A : C {
std::unique_ptr<B> x;
};





share|improve this answer















virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.



There are two ways you can fix this. You can add a move constructor like



struct A{
std::unique_ptr<B> x;

A() = default; // you have to add this since the move constructor was added
A(A&&) = default; // defaulted move
virtual ~A() = default;
};


or you can create a base class that has the virtual destructor and inherit from that like



struct C {
virtual ~C() = default;
};

struct A : C {
std::unique_ptr<B> x;
};






share|improve this answer














share|improve this answer



share|improve this answer








edited 5 hours ago

























answered 5 hours ago









NathanOliverNathanOliver

96k16136209




96k16136209








  • 6





    Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

    – 0x5453
    5 hours ago






  • 2





    @0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

    – NathanOliver
    5 hours ago






  • 2





    @Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

    – eerorika
    5 hours ago








  • 3





    @Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

    – Angew
    5 hours ago






  • 3





    @Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

    – NathanOliver
    5 hours ago
















  • 6





    Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

    – 0x5453
    5 hours ago






  • 2





    @0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

    – NathanOliver
    5 hours ago






  • 2





    @Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

    – eerorika
    5 hours ago








  • 3





    @Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

    – Angew
    5 hours ago






  • 3





    @Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

    – NathanOliver
    5 hours ago










6




6





Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

– 0x5453
5 hours ago





Better to follow the Rule of Zero/Five. Either add all of (copy ctor, move ctor, copy assignment, move assignment, destructor) or add none of them. In this example, none of them are necessary.

– 0x5453
5 hours ago




2




2





@0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

– NathanOliver
5 hours ago





@0x5453 Unless this is a parent class and the OP wants the derived classes to get destroyed properly. You need a virtual destructor if you have polymorphism.

– NathanOliver
5 hours ago




2




2





@Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

– eerorika
5 hours ago







@Tzalumen no delete is required (because that's what the unique pointer does for you), but a virtual destructor is required so that the unique pointer won't have UB.

– eerorika
5 hours ago






3




3





@Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

– Angew
5 hours ago





@Tzalumen If you delete an object of class X through a pointer to a base class of X and that base class doesn't have a virtual dtor, it's Undefined Behaviour. Regardless of what the destructor does.

– Angew
5 hours ago




3




3





@Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

– NathanOliver
5 hours ago







@Tzalumen If you have polymorphism, you must have a virtual destructor. If you don't the destructor for the derived class won't be called and you have UB.

– NathanOliver
5 hours ago














Sobuch is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Sobuch is a new contributor. Be nice, and check out our Code of Conduct.













Sobuch is a new contributor. Be nice, and check out our Code of Conduct.












Sobuch 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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55288708%2fc-copy-constructor-called-at-return%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

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)