Deep-copying a derived class when its base class has member pointersWhat is a smart pointer and when should I use one?What is the difference between a deep copy and a shallow copy?How to call a parent class function from derived class function?Method of derived class needs to downcast its parameterMaking a copy of an object of abstract base classc++ design: reducing coupling in a deep class hierarchyreturning instance of derived class from base class member functionIssue writing a generic copy constructor for the base of a CRTP classCrash at “vtable for __cxxabiv1::__class_type_info ()” mean?C++ — Polymorphic Deep copy
Is encryption still applied if you ignore the SSL certificate warning for self signed?
How to tell the object type of an Attachment
Pauli exclusion principle - black holes
Last-minute canceled work-trip mean I'll lose thousands of dollars on planned vacation
What makes MOVEQ quicker than a normal MOVE in 68000 assembly?
Why is Google approaching my VPS machine?
Grouping into more groups in one iteration
Is it possible to have a career in SciComp without contributing to arms research?
Software need db owner permission to master database (sql2016)
An entire function all whose forward orbits are bounded
Is surviving this (blood loss) scenario possible?
How did Jayne know when to shoot?
Term “console” in game consoles
Locked-up DOS computer beeped on keypress. What mechanism caused that?
I have found a mistake on someone's code published online: what is the protocol?
How to find location on Cambridge-Mildenhall railway that still has tracks/rails?
What is the period of Langton's ant on a torus?
Why does a tetrahedral molecule like methane have a dipole moment of zero?
How fast does a character need to move to be effectively invisible?
Why aren't there any women super GMs?
Why a binary file is not shown as 0 and 1?
Cauchy reals and Dedekind reals satisfy "the same mathematical theorems"
Difference between c++14 and c++17 using: `*p++ = *p`
Is straight-up writing someone's opinions telling?
Deep-copying a derived class when its base class has member pointers
What is a smart pointer and when should I use one?What is the difference between a deep copy and a shallow copy?How to call a parent class function from derived class function?Method of derived class needs to downcast its parameterMaking a copy of an object of abstract base classc++ design: reducing coupling in a deep class hierarchyreturning instance of derived class from base class member functionIssue writing a generic copy constructor for the base of a CRTP classCrash at “vtable for __cxxabiv1::__class_type_info ()” mean?C++ — Polymorphic Deep copy
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am trying to make a deep copy of the object d
of class Derived
as in the code below:
class A
public:
int m_int;
A* clone()
return new A(*this);
;
class Base
public:
A* m_a;
virtual Base* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Base* clone = new Base(*this);
clone->m_a = new_a;
return clone;
;
class Derived : public Base
public:
double m_dbl;
virtual Derived* clone()
return new Derived(*this);
;
int main()
Derived* d = new Derived();
d->m_dbl = 1.234;
A* a = new A();
a->m_int = -1;
d->m_a = a;
//clone d
Derived d_copy = d->clone();
//changing values of d's attributes must not affect d_copy
a->m_int = 10;
d->m_dbl = 3.456;
//check d_copy
cout << "m_int " << d_copy->m_a->m_int << endl;
cout << "m_dbl " << d_copy->m_dbl << endl;
output:
m_int 10 //wrong, should be -1;
m_dbl 1.234 //correct
As you can see, simply returning new Derived(*this)
in Derived's clone()
method is wrong since it does not deep-copy m_a
.
If I "bring down" the deep-copying of m_a
from Base
to Derived
then I will get the correct answer:
virtual Base* clone() = 0;
...
virtual Derived* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Derived* clone = new Derived(*this);
clone->m_a = new_a;
return new Derived(*this);
//gives out m_int = -1
If this is the case does this mean that each time I create further derived classes from Derived
, I always have to "bring down" the contents of clone()
to them?
Also, if for example Base
has two derived classes Derived1
and Derived2
, does this mean that I have to deep-copy the members of Base
in each of them?
Any other ways to approach this?
c++ inheritance deep-copy
add a comment |
I am trying to make a deep copy of the object d
of class Derived
as in the code below:
class A
public:
int m_int;
A* clone()
return new A(*this);
;
class Base
public:
A* m_a;
virtual Base* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Base* clone = new Base(*this);
clone->m_a = new_a;
return clone;
;
class Derived : public Base
public:
double m_dbl;
virtual Derived* clone()
return new Derived(*this);
;
int main()
Derived* d = new Derived();
d->m_dbl = 1.234;
A* a = new A();
a->m_int = -1;
d->m_a = a;
//clone d
Derived d_copy = d->clone();
//changing values of d's attributes must not affect d_copy
a->m_int = 10;
d->m_dbl = 3.456;
//check d_copy
cout << "m_int " << d_copy->m_a->m_int << endl;
cout << "m_dbl " << d_copy->m_dbl << endl;
output:
m_int 10 //wrong, should be -1;
m_dbl 1.234 //correct
As you can see, simply returning new Derived(*this)
in Derived's clone()
method is wrong since it does not deep-copy m_a
.
If I "bring down" the deep-copying of m_a
from Base
to Derived
then I will get the correct answer:
virtual Base* clone() = 0;
...
virtual Derived* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Derived* clone = new Derived(*this);
clone->m_a = new_a;
return new Derived(*this);
//gives out m_int = -1
If this is the case does this mean that each time I create further derived classes from Derived
, I always have to "bring down" the contents of clone()
to them?
Also, if for example Base
has two derived classes Derived1
and Derived2
, does this mean that I have to deep-copy the members of Base
in each of them?
Any other ways to approach this?
c++ inheritance deep-copy
why ism_a
a pointer? If it was an object you'd get deep copies for free
– formerlyknownas_463035818
Mar 26 at 10:05
1
There's a memory leak inBase::clone
.
– molbdnilo
Mar 26 at 10:09
1
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12
add a comment |
I am trying to make a deep copy of the object d
of class Derived
as in the code below:
class A
public:
int m_int;
A* clone()
return new A(*this);
;
class Base
public:
A* m_a;
virtual Base* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Base* clone = new Base(*this);
clone->m_a = new_a;
return clone;
;
class Derived : public Base
public:
double m_dbl;
virtual Derived* clone()
return new Derived(*this);
;
int main()
Derived* d = new Derived();
d->m_dbl = 1.234;
A* a = new A();
a->m_int = -1;
d->m_a = a;
//clone d
Derived d_copy = d->clone();
//changing values of d's attributes must not affect d_copy
a->m_int = 10;
d->m_dbl = 3.456;
//check d_copy
cout << "m_int " << d_copy->m_a->m_int << endl;
cout << "m_dbl " << d_copy->m_dbl << endl;
output:
m_int 10 //wrong, should be -1;
m_dbl 1.234 //correct
As you can see, simply returning new Derived(*this)
in Derived's clone()
method is wrong since it does not deep-copy m_a
.
If I "bring down" the deep-copying of m_a
from Base
to Derived
then I will get the correct answer:
virtual Base* clone() = 0;
...
virtual Derived* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Derived* clone = new Derived(*this);
clone->m_a = new_a;
return new Derived(*this);
//gives out m_int = -1
If this is the case does this mean that each time I create further derived classes from Derived
, I always have to "bring down" the contents of clone()
to them?
Also, if for example Base
has two derived classes Derived1
and Derived2
, does this mean that I have to deep-copy the members of Base
in each of them?
Any other ways to approach this?
c++ inheritance deep-copy
I am trying to make a deep copy of the object d
of class Derived
as in the code below:
class A
public:
int m_int;
A* clone()
return new A(*this);
;
class Base
public:
A* m_a;
virtual Base* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Base* clone = new Base(*this);
clone->m_a = new_a;
return clone;
;
class Derived : public Base
public:
double m_dbl;
virtual Derived* clone()
return new Derived(*this);
;
int main()
Derived* d = new Derived();
d->m_dbl = 1.234;
A* a = new A();
a->m_int = -1;
d->m_a = a;
//clone d
Derived d_copy = d->clone();
//changing values of d's attributes must not affect d_copy
a->m_int = 10;
d->m_dbl = 3.456;
//check d_copy
cout << "m_int " << d_copy->m_a->m_int << endl;
cout << "m_dbl " << d_copy->m_dbl << endl;
output:
m_int 10 //wrong, should be -1;
m_dbl 1.234 //correct
As you can see, simply returning new Derived(*this)
in Derived's clone()
method is wrong since it does not deep-copy m_a
.
If I "bring down" the deep-copying of m_a
from Base
to Derived
then I will get the correct answer:
virtual Base* clone() = 0;
...
virtual Derived* clone()
A* new_a = new A();
new_a = this->m_a->clone();
Derived* clone = new Derived(*this);
clone->m_a = new_a;
return new Derived(*this);
//gives out m_int = -1
If this is the case does this mean that each time I create further derived classes from Derived
, I always have to "bring down" the contents of clone()
to them?
Also, if for example Base
has two derived classes Derived1
and Derived2
, does this mean that I have to deep-copy the members of Base
in each of them?
Any other ways to approach this?
c++ inheritance deep-copy
c++ inheritance deep-copy
asked Mar 26 at 9:55
nicetyartworknicetyartwork
1
1
why ism_a
a pointer? If it was an object you'd get deep copies for free
– formerlyknownas_463035818
Mar 26 at 10:05
1
There's a memory leak inBase::clone
.
– molbdnilo
Mar 26 at 10:09
1
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12
add a comment |
why ism_a
a pointer? If it was an object you'd get deep copies for free
– formerlyknownas_463035818
Mar 26 at 10:05
1
There's a memory leak inBase::clone
.
– molbdnilo
Mar 26 at 10:09
1
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12
why is
m_a
a pointer? If it was an object you'd get deep copies for free– formerlyknownas_463035818
Mar 26 at 10:05
why is
m_a
a pointer? If it was an object you'd get deep copies for free– formerlyknownas_463035818
Mar 26 at 10:05
1
1
There's a memory leak in
Base::clone
.– molbdnilo
Mar 26 at 10:09
There's a memory leak in
Base::clone
.– molbdnilo
Mar 26 at 10:09
1
1
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12
add a comment |
1 Answer
1
active
oldest
votes
You can consider of implementing the copy constructor that always is doing deep copy. In such case your clone
implementation will always be trivial:
class Base
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
virtual Base* clone()
return new A(*this);
;
class Derived : public Base
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone()
return new Derived(*this);
;
If you don't want to change the behavior of the default constructor (you want the default constructor to make shallow copy for example) the alternative is to move copy implementation to a CopyTo
method, so you can reuse it:
class Base
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
to.m_a = from.m_a->clone();
virtual Base* clone()
Base* result = new Base();
CopyTo(*this, result);
return result;
;
class Derived : public Base
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
virtual Derived * clone()
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
virtual Derived* clone()
return new Derived(*this);
;
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%2f55354198%2fdeep-copying-a-derived-class-when-its-base-class-has-member-pointers%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
You can consider of implementing the copy constructor that always is doing deep copy. In such case your clone
implementation will always be trivial:
class Base
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
virtual Base* clone()
return new A(*this);
;
class Derived : public Base
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone()
return new Derived(*this);
;
If you don't want to change the behavior of the default constructor (you want the default constructor to make shallow copy for example) the alternative is to move copy implementation to a CopyTo
method, so you can reuse it:
class Base
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
to.m_a = from.m_a->clone();
virtual Base* clone()
Base* result = new Base();
CopyTo(*this, result);
return result;
;
class Derived : public Base
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
virtual Derived * clone()
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
virtual Derived* clone()
return new Derived(*this);
;
add a comment |
You can consider of implementing the copy constructor that always is doing deep copy. In such case your clone
implementation will always be trivial:
class Base
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
virtual Base* clone()
return new A(*this);
;
class Derived : public Base
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone()
return new Derived(*this);
;
If you don't want to change the behavior of the default constructor (you want the default constructor to make shallow copy for example) the alternative is to move copy implementation to a CopyTo
method, so you can reuse it:
class Base
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
to.m_a = from.m_a->clone();
virtual Base* clone()
Base* result = new Base();
CopyTo(*this, result);
return result;
;
class Derived : public Base
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
virtual Derived * clone()
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
virtual Derived* clone()
return new Derived(*this);
;
add a comment |
You can consider of implementing the copy constructor that always is doing deep copy. In such case your clone
implementation will always be trivial:
class Base
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
virtual Base* clone()
return new A(*this);
;
class Derived : public Base
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone()
return new Derived(*this);
;
If you don't want to change the behavior of the default constructor (you want the default constructor to make shallow copy for example) the alternative is to move copy implementation to a CopyTo
method, so you can reuse it:
class Base
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
to.m_a = from.m_a->clone();
virtual Base* clone()
Base* result = new Base();
CopyTo(*this, result);
return result;
;
class Derived : public Base
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
virtual Derived * clone()
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
virtual Derived* clone()
return new Derived(*this);
;
You can consider of implementing the copy constructor that always is doing deep copy. In such case your clone
implementation will always be trivial:
class Base
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
virtual Base* clone()
return new A(*this);
;
class Derived : public Base
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone()
return new Derived(*this);
;
If you don't want to change the behavior of the default constructor (you want the default constructor to make shallow copy for example) the alternative is to move copy implementation to a CopyTo
method, so you can reuse it:
class Base
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
to.m_a = from.m_a->clone();
virtual Base* clone()
Base* result = new Base();
CopyTo(*this, result);
return result;
;
class Derived : public Base
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
virtual Derived * clone()
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
virtual Derived* clone()
return new Derived(*this);
;
answered Mar 26 at 10:18
Dmitry GordonDmitry Gordon
1,7696 silver badges16 bronze badges
1,7696 silver badges16 bronze badges
add a comment |
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
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%2f55354198%2fdeep-copying-a-derived-class-when-its-base-class-has-member-pointers%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
why is
m_a
a pointer? If it was an object you'd get deep copies for free– formerlyknownas_463035818
Mar 26 at 10:05
1
There's a memory leak in
Base::clone
.– molbdnilo
Mar 26 at 10:09
1
Why don't you make deep-copying copy constructors? Copying is what they're for, after all.
– molbdnilo
Mar 26 at 10:12