1 / 27

Dynamic Data, Shallow Copies, and Deep Copies

Dynamic Data, Shallow Copies, and Deep Copies. Problem. Consider the following program that creates a grade tree makes a copy of the tree to save modifies the original tree. #include “stutree.h” int main() { Gradetree mygrades; // list of my grades

Download Presentation

Dynamic Data, Shallow Copies, and Deep Copies

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dynamic Data, Shallow Copies, and Deep Copies

  2. Problem • Consider the following program that • creates a grade tree • makes a copy of the tree to save • modifies the original tree

  3. #include “stutree.h” int main() { Gradetree mygrades; // list of my grades mygrades.Insert(90); // put some grades in my list mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; // save a copy of my grades at this point in term savemygrades = mygrades; mygrades.Insert(99); // add/delete more grades mygrades.Delete(86); }

  4. NULL #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root

  5. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root

  6. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86

  7. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86 97

  8. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86 97 NULL savemygrades.root

  9. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86 97 savemygrades.root

  10. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86 97 This is called a shallow copy Only the private data is copied to the new class instance There is really only one copy of the dynamic data! savemygrades.root

  11. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 86 97 99 savemygrades.root

  12. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 97 99 savemygrades.root

  13. 90 #include “stutree.h” int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); Gradetree savemygrades; savemygrades = mygrades; mygrades.Insert(99); mygrades.Delete(86); } mygrades.root 97 99 savemygrades.root Problem: I really didn’t get two copies of my grades, so when I make changes to mygrades, I really am changing both mygrades and savemygrades!

  14. Problem • Consider the following program that • creates a grade tree • calls a function, passing the grade tree by value • modifies the copy of the tree passed to the function • returns to the main function

  15. #include “stutree.h” void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); } 90 mygrades.root 86 97

  16. #include “stutree.h” Void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); } tempgrades.root 90 mygrades.root 86 97

  17. #include “stutree.h” Void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); } tempgrades.root 90 mygrades.root 86 97 99

  18. #include “stutree.h” Void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); } tempgrades.root 90 mygrades.root 97 99

  19. Problem: Passing a class by value only gives a shallow copy, so function actually modifies mygrades! #include “stutree.h” Void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); } tempgrades.root 90 mygrades.root 97 99

  20. #include “stutree.h” Void GradeFunction (Gradetree tempgrades) { tempgrades.Insert(99); tempgrades.Delete(86); } int main() { Gradetree mygrades; mygrades.Insert(90); mygrades.Insert(86); mygrades.Insert(97); GradeFunction(mygrades); // execution continues here after function call } 90 mygrades.root 97 99

  21. Solution • We need deep copies in the two previous situations • A deep copy is a copy of not only the private root pointer, but also a copy of all of the dynamic data, i.e., a copy of all nodes in the entire tree • Can you think of other classes we have used that needed deep copies? • any class using linked lists (files gradelnklist, stackll, queuell)

  22. Solution (continued) • Add a function to the Gradetree class that makes a deep copy when the assignment operator is used • This is a function that overloads the assignment operator, i.e., the = sign. • I actually already included this function in the Gradetree class

  23. Solution (continued) • Add a function to the Gradetree class that makes a deep copy when the class is passed by value to a function • This is a function called a copy constructor. • The copy constructor is called when a class is passed by value. • I actually already included this function in the Gradetree class

  24. stutree.h class Gradetree { public: // default constructor Gradetree (); // copy constructor - for deep copies Gradetree (const Gradetree& othergradetree); // destructor ~Gradetree (); // overload assignment for deep copies void operator= (const Gradetree& othergradetree); . . . private: Treenode* copytree (Treenode* t); // used by copy constructor and operator= void destroytree (Treenode* t); // used by destructor . . . Treenode* root; };

  25. stutree.cpp // copy constructor - for deep copies Gradetree::Gradetree (const Gradetree& othergradetree) { root = copytree (othergradetree.root); } // overload assignment for deep copies void Gradetree::operator= (const Gradetree& othergradetree) { root = copytree (othergradetree.root); }

  26. stutree.cpp // used by copy constructor and operator= Treenode* Gradetree::copytree (Treenode* t) { Treenode* tmp = NULL; // for building copy of t if (t != NULL) { tmp = new Treenode; tmp->grade = t->grade; tmp->count = t->count; tmp->left = copytree (t->left); tmp->right = copytree (t->right); } return tmp; }

  27. For more information • see section 6.5 in text – pp. 360 - 370

More Related