Title: Dynamic Data, Shallow Copies, and Deep Copies
1Dynamic Data, Shallow Copies, and Deep Copies
2Problem
- Consider the following program that
- creates a grade tree
- makes a copy of the tree to save
- modifies the original tree
3include 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)
4NULL
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
590
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
690
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
790
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
890
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
990
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
1090
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
1190
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
1290
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
1390
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 didnt get two copies of my
grades, so when I make changes to mygrades, I
really am changing both mygrades and savemygrades!
14Problem
- 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
15include 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
16include 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
17include 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
18include 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
19Problem 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
20include 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
21Solution
- 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)
22Solution (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
23Solution (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
24stutree.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
25stutree.cpp
// copy constructor - for deep copies GradetreeG
radetree (const Gradetree othergradetree)
root copytree (othergradetree.root)
// overload assignment for deep copies void
Gradetreeoperator (const Gradetree
othergradetree) root copytree
(othergradetree.root)
26stutree.cpp
// used by copy constructor and
operator Treenode Gradetreecopytree
(Treenode t) Treenode tmp NULL // for
building copy of t if (t ! NULL)
tmp new Treenode tmp-gtgrade
t-gtgrade tmp-gtcount t-gtcount
tmp-gtleft copytree (t-gtleft)
tmp-gtright copytree (t-gtright)
return tmp
27For more information
- see section 6.5 in text pp. 360 - 370