C++ copy constructor called at return
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++
New contributor
add a comment |
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++
New contributor
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 youreturn tmp
then you're asking it to make a copy oftmp
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
add a comment |
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++
New contributor
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++
c++
New contributor
New contributor
edited 4 hours ago
Sobuch
New contributor
asked 5 hours ago
SobuchSobuch
485
485
New contributor
New contributor
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 youreturn tmp
then you're asking it to make a copy oftmp
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
add a comment |
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 youreturn tmp
then you're asking it to make a copy oftmp
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
add a comment |
1 Answer
1
active
oldest
votes
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;
};
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 youdelete
an object of classX
through a pointer to a base class ofX
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
|
show 24 more comments
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.
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%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
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;
};
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 youdelete
an object of classX
through a pointer to a base class ofX
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
|
show 24 more comments
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;
};
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 youdelete
an object of classX
through a pointer to a base class ofX
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
|
show 24 more comments
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;
};
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;
};
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 youdelete
an object of classX
through a pointer to a base class ofX
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
|
show 24 more comments
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 youdelete
an object of classX
through a pointer to a base class ofX
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
|
show 24 more comments
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.
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.
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%2f55288708%2fc-copy-constructor-called-at-return%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
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 youreturn tmp
then you're asking it to make a copy oftmp
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