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;








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?










share|improve this question






















  • 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


















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?










share|improve this question






















  • 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














0












0








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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 26 at 9:55









nicetyartworknicetyartwork

1




1












  • 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


















  • 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

















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













1 Answer
1






active

oldest

votes


















0














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

;





share|improve this answer






















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









    0














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

    ;





    share|improve this answer



























      0














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

      ;





      share|improve this answer

























        0












        0








        0







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

        ;





        share|improve this answer













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

        ;






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 26 at 10:18









        Dmitry GordonDmitry Gordon

        1,7696 silver badges16 bronze badges




        1,7696 silver badges16 bronze badges


















            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.



















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





















































            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

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현