Title: Nell Dale
1C Plus Data Structures
Nell Dale David Teague Excerpt from Chapter
6 Copy Constructor Slides by Sylvia Sorkin,
Community College of Baltimore County - Essex
Campus
2Recall Definition of Stack
- Logical (or ADT) level A stack is an ordered
group of homogeneous items (elements), in which
the removal and addition of stack items can take
place only at the top of the stack. - A stack is a LIFO last in, first out structure.
3Stack ADT Operations
- clear -- Sets stack to an empty state.
- empty -- Determines whether the stack is
currently empty. -
- full -- Determines whether the stack is currently
full. - push (const SE newElem) -- Adds newElem to the
top of the stack. -
- pop () -- Removes the item at the top of the
stack and returns it
3
4 class Stackltintgt
5 What happens . . .
- When a function is called that uses pass by
value for a class object like our dynamically
linked stack?
6Passing a class object by value
- // FUNCTION CODE
- templateltclass SEgt
- void dummy( StackltSEgt copyStack )
- // Uses pass by value
-
- .
- .
- .
- .
6
7 Pass by value makes a shallow copy
Stackltintgt testStack // CLIENT
CODE . . . dummy(
copyStack ) // function call
testStack
copyStack
Private data top 7000
Private data 7000
6000 top 7000
20 30
shallow copy
8Shallow Copy vs. Deep Copy
- A shallow copy copies only the class data
members, and does not copy any pointed-to data. - A deep copy copies not only the class data
members, but also makes separately stored copies
of any pointed-to data.
9Whats the difference?
- A shallow copy shares the pointed to data with
the original class object. - A deep copy stores its own copy of the pointed to
data at different locations than the data in the
original class object.
10 Making a deep copy
testStack
Private data 7000
6000 top 7000
20 30
copyStack
Private data 5000
2000 top 5000
20 30
deep copy
11Suppose dummy Uses Pop
- // FUNCTION CODE
- templateltclass SEgt
- void dummy( StackltSEgt copyStack )
- // Uses pass by value
-
- SE item
- item copyStack.Pop()
- .
- .
- .
-
- WHAT HAPPENS IN THE SHALLOW COPY SCENARIO?
11
12 testStack.top is left dangling
Stackltintgt testStack // CLIENT CODE
. . . dummy( testStack )
testStack
SomeStack
Private data top 6000
Private data 7000
6000 top 7000
? 30
shallow copy
13 MyStack.topPtr is left dangling
NOTICE THAT NOT JUST FOR THE SHALLOW COPY, BUT
ALSO FOR ARGUMENT testStack, THE DYNAMIC DATA
HAS CHANGED!
testStack
copyStack
Private data top 6000
Private data 7000
6000 top 7000
? 30
shallow copy
14As a result . . .
- This default method used for pass by value is not
the best way when a data member pointer points to
dynamic data. - Instead, you should write what is called a copy
constructor, which makes a deep copy of the
dynamic data in a different memory location.
15More about copy constructors
- When there is a copy constructor provided for a
class, the copy constructor is used to make
copies for pass by value. - You do not call the copy constructor.
- Like other constructors, it has no return type.
- Because the copy constructor properly defines
pass by value for your class, it must use pass by
reference in its definition.
16Copy Constructor
- Copy constructor is a special member function of
a class that is implicitly called in these three
situations - passing object parameters by value,
- initializing an object variable in a
declaration, - returning an object as the return value of a
function.
17- // DYNAMICALLY LINKED IMPLEMENTATION OF STACK
- template lt class SE gt
- class Stack
-
- public
- // Constructor
- Stack ( int ignored 0 )
-
- // Copy constructor// Implicitly called for
pass by value - Stack ( const Stack valueStack )
-
- // Destructor
- Stack ()
- . .
- .
- private
- // Data member
17
18Classes with Data Member Pointers Need
- CLASS ASSIGNMENT OPERATOR
- CLASS COPY CONSTRUCTOR
- CLASS DESTRUCTOR
19- template lt class SE gt
- StackltSEgt Stack ( const Stack valueStack )
// Copy constructor -
- StackNodeltSEgt ourp // ptr for our stack
- StackNodeltSEgt otherp // ptr for other value
Stack - if (valueStack.top0)
- top0
- else // allocate memory for first node
-
- topnew StackNodeltSEgt(valueStack.top-gtelement,
0) - ourptop
- otherpvalueStack.top-gtnext
- while(otherp!0) // deep copy other nodes
-
- ourp-gtnextnew StackNodeltSEgt(otherp-gtelement,
0) - otherpotherp-gtnext
- ourpourp-gtnext
-
-
19
20What about the assignment operator?
- The default method used for assignment of class
objects makes a shallow copy. - If your class has a data member pointer to
dynamic data, you should write a member function
to overload the assignment operator to make a
deep copy of the dynamic data. - The assignment operator is like copy const but it
also has to delete old data (if any) first
21- // DYNAMICALLY LINKED IMPLEMENTATION OF STACK
WITH ASSIGNMENT OPERATOR - templateltclass SEgt
- class Stack
-
- public
- // Constructor
- Stack ( int ignored 0 )
-
- // Copy constructor
- Stack ( const Stack valueStack )
-
- void operator ( StackltSEgt rightStack )
////////////////// - // Overloads assignment operator.
//\\\\\\\\\\\\\\\\ - // Destructor
- Stack ()
- . .
21
22Use of the assignment operator
- Stackltintgt myStack, yourStack
-
- // Fill both stacks with data
-
- myStackyourStack //invokes assign op
- myStack is host who is being rebuilt
- (its his assignment operator being used)
- yourStack is rightStack, parameter to the
operator definition
23- template lt class SE gt // ASSIGNMENT OPERATOR
- void StackltSEgt operator ( StackltSEgt
rightStack ) -
- clear() // remove old data from our Stack
- StackNodeltSEgt ourp // ptr for our stack
- StackNodeltSEgt otherp // ptr for other
rightStack - if (rightStack.top0)
- top0
- else // allocate memory for first node
-
- topnew StackNodeltSEgt(rightStack.top-gtelement,
0) - ourptop
- otherprightStack.top-gtnext
- while(otherp!0) // deep copy other nodes
-
- ourp-gtnextnew StackNodeltSEgt(otherp-gtelement,
0) - otherpotherp-gtnext
- ourpourp-gtnext
-
23
24Conclusion
- If your class includes members that are pointers
to dynamic memory - You should declare a Constructor, Destructor,
Copy Constructor, Assignment Operator
25ExprTree Copy Constructor
- If you still want to try it, heres some hints
26- // EXPRESSION TREE CLASS DEFINITION
- templateltclass SEgt
- class ExprTree
-
- public
- ExprTree () // Constructor
- ExprTree () // Destructor
- .
- .
- .
- // Copy constructor
- ExprTree ( const ExprTree valueTree )
- private
- // Recursive partner of Copy Constructor
- void CopySub(ExprTreeNode p, const
ExprTreeNode valuePtr) - // Data member
26
27ExprTree Copy Constructor Algorithm
- ExprTreeExprTree ( const ExprTree valueTree )
-
- CopySub(root, valueTree.root)
-
- //--------------------------------------------
- void ExprTreeCopySub(ExprTreeNode p, const
ExprTreeNode valuePtr) -
- //If valuePtr is not zero
- // make p point to a new node with valuePtrs
data, and - // Null left right ptrs
- //
- // call CopySub on the left children of both
trees - // and on right children
-