C++ copy constructor called at return The Next CEO of Stack OverflowWhen to use virtual destructors?In which situations is the C++ copy constructor called?What are the differences between a pointer variable and a reference variable in C++?Why don't C++ compilers define operator== and operator!=?What is the lifetime of a static variable in a C++ function?Can I call a constructor from another constructor (do constructor chaining) in C++?Inheriting constructorsHow can I profile C++ code running on Linux?The Definitive C++ Book Guide and ListWhen to use virtual destructors?What is the “-->” operator in C++?What is the copy-and-swap idiom?

Why doesn't Shulchan Aruch include the laws of destroying fruit trees?

How to pronounce fünf in 45

What difference does it make matching a word with/without a trailing whitespace?

How does a dynamic QR code work?

Why can't we say "I have been having a dog"?

Why do we say “un seul M” and not “une seule M” even though M is a “consonne”?

How badly should I try to prevent a user from XSSing themselves?

How to show a landlord what we have in savings?

How should I connect my cat5 cable to connectors having an orange-green line?

Direct Implications Between USA and UK in Event of No-Deal Brexit

Would a grinding machine be a simple and workable propulsion system for an interplanetary spacecraft?

Can this transistor (2N2222) take 6 V on emitter-base? Am I reading the datasheet incorrectly?

Can Sri Krishna be called 'a person'?

Strange use of "whether ... than ..." in official text

How to implement Comparable so it is consistent with identity-equality

Is it reasonable to ask other researchers to send me their previous grant applications?

Is the offspring between a demon and a celestial possible? If so what is it called and is it in a book somewhere?

Planeswalker Ability and Death Timing

Could a dragon use its wings to swim?

Does Germany produce more waste than the US?

A hang glider, sudden unexpected lift to 25,000 feet altitude, what could do this?

What happens if you break a law in another country outside of that country?

Is a distribution that is normal, but highly skewed, considered Gaussian?

How exploitable/balanced is this homebrew spell: Spell Permanency?



C++ copy constructor called at return



The Next CEO of Stack OverflowWhen to use virtual destructors?In which situations is the C++ copy constructor called?What are the differences between a pointer variable and a reference variable in C++?Why don't C++ compilers define operator== and operator!=?What is the lifetime of a static variable in a C++ function?Can I call a constructor from another constructor (do constructor chaining) in C++?Inheriting constructorsHow can I profile C++ code running on Linux?The Definitive C++ Book Guide and ListWhen to use virtual destructors?What is the “-->” operator in C++?What is the copy-and-swap idiom?










17















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



















  • 1





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

    – kmdreko
    Mar 21 at 20:29






  • 5





    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
    Mar 21 at 20:29






  • 3





    @Everyone except that it is usually a move rather than a copy, which is what the question is about.

    – Quentin
    Mar 22 at 9:24











  • A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

    – Adrian
    7 hours ago















17















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



















  • 1





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

    – kmdreko
    Mar 21 at 20:29






  • 5





    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
    Mar 21 at 20:29






  • 3





    @Everyone except that it is usually a move rather than a copy, which is what the question is about.

    – Quentin
    Mar 22 at 9:24











  • A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

    – Adrian
    7 hours ago













17












17








17


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
















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















share|improve this question













share|improve this question




share|improve this question








edited Mar 21 at 21:18







Sobuch

















asked Mar 21 at 20:23









SobuchSobuch

886




886







  • 1





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

    – kmdreko
    Mar 21 at 20:29






  • 5





    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
    Mar 21 at 20:29






  • 3





    @Everyone except that it is usually a move rather than a copy, which is what the question is about.

    – Quentin
    Mar 22 at 9:24











  • A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

    – Adrian
    7 hours ago












  • 1





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

    – kmdreko
    Mar 21 at 20:29






  • 5





    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
    Mar 21 at 20:29






  • 3





    @Everyone except that it is usually a move rather than a copy, which is what the question is about.

    – Quentin
    Mar 22 at 9:24











  • A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

    – Adrian
    7 hours ago







1




1





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

– kmdreko
Mar 21 at 20:29





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

– kmdreko
Mar 21 at 20:29




5




5





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
Mar 21 at 20:29





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
Mar 21 at 20:29




3




3





@Everyone except that it is usually a move rather than a copy, which is what the question is about.

– Quentin
Mar 22 at 9:24





@Everyone except that it is usually a move rather than a copy, which is what the question is about.

– Quentin
Mar 22 at 9:24













A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

– Adrian
7 hours ago





A little surprising as I would have thought that RVO would have been invoked, resulting in no move or copy.

– Adrian
7 hours ago












1 Answer
1






active

oldest

votes


















30














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


This works because A no longer has a user declared destructor (Yes, C does but we only care about A) so it will still generate a move constructor in A. The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means
C's copy constructor is called in A's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.






share|improve this answer




















  • 10





    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
    Mar 21 at 20:33






  • 3





    @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
    Mar 21 at 20:34






  • 3





    @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
    Mar 21 at 20:40







  • 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
    Mar 21 at 20:41






  • 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
    Mar 21 at 20:41












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









30














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


This works because A no longer has a user declared destructor (Yes, C does but we only care about A) so it will still generate a move constructor in A. The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means
C's copy constructor is called in A's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.






share|improve this answer




















  • 10





    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
    Mar 21 at 20:33






  • 3





    @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
    Mar 21 at 20:34






  • 3





    @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
    Mar 21 at 20:40







  • 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
    Mar 21 at 20:41






  • 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
    Mar 21 at 20:41
















30














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


This works because A no longer has a user declared destructor (Yes, C does but we only care about A) so it will still generate a move constructor in A. The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means
C's copy constructor is called in A's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.






share|improve this answer




















  • 10





    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
    Mar 21 at 20:33






  • 3





    @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
    Mar 21 at 20:34






  • 3





    @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
    Mar 21 at 20:40







  • 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
    Mar 21 at 20:41






  • 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
    Mar 21 at 20:41














30












30








30







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


This works because A no longer has a user declared destructor (Yes, C does but we only care about A) so it will still generate a move constructor in A. The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means
C's copy constructor is called in A's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.






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


This works because A no longer has a user declared destructor (Yes, C does but we only care about A) so it will still generate a move constructor in A. The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means
C's copy constructor is called in A's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 22 at 12:44

























answered Mar 21 at 20:32









NathanOliverNathanOliver

97.6k16138214




97.6k16138214







  • 10





    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
    Mar 21 at 20:33






  • 3





    @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
    Mar 21 at 20:34






  • 3





    @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
    Mar 21 at 20:40







  • 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
    Mar 21 at 20:41






  • 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
    Mar 21 at 20:41













  • 10





    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
    Mar 21 at 20:33






  • 3





    @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
    Mar 21 at 20:34






  • 3





    @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
    Mar 21 at 20:40







  • 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
    Mar 21 at 20:41






  • 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
    Mar 21 at 20:41








10




10





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
Mar 21 at 20:33





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
Mar 21 at 20:33




3




3





@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
Mar 21 at 20:34





@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
Mar 21 at 20:34




3




3





@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
Mar 21 at 20:40






@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
Mar 21 at 20:40





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
Mar 21 at 20:41





@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
Mar 21 at 20:41




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
Mar 21 at 20:41






@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
Mar 21 at 20:41




















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.




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

He _____ here since 1970 . Answer needed [closed]What does “since he was so high” mean?Meaning of “catch birds for”?How do I ensure “since” takes the meaning I want?“Who cares here” meaningWhat does “right round toward” mean?the time tense (had now been detected)What does the phrase “ring around the roses” mean here?Correct usage of “visited upon”Meaning of “foiled rail sabotage bid”It was the third time I had gone to Rome or It is the third time I had been to Rome

Bunad

Færeyskur hestur Heimild | Tengill | Tilvísanir | LeiðsagnarvalRossið - síða um færeyska hrossið á færeyskuGott ár hjá færeyska hestinum