Data Structures CSCI 262, Spring 2002 Lecture 2 Classes and

Data Structures
CSCI 132, Spring 2014
Lecture 12
Destructors, Copy Constructors and Overloading
1
Stacks as Linked lists
top_node
top
entry
middle
entry
bottom
entry
typedef Stack_entry Node_entry;
class Stack {
public:
Stack( );
bool empty( );
Error_code push( const Stack_entry &item);
Error_code pop( );
Error_code top(Stack_entry &item) const;
protected:
Node *top_node;
}
2
Clients creating garbage
for (int i = 0; i < 1000000; i++) {
Stack small;
small.push(some_data);
}
•
Problem: small exists only within for loop. It is created
repeatedly (1000000 times!) and goes out of scope
outside of loop.
•
Memory is allocated, but not freed up.
•
Solution: Use a Destructor function
3
The Stack destructor
Stack :: ~Stack( ) {
while (!empty( ) ) {
pop( );
//pop( ) deletes nodes
}
}
•
•
Destructors are called automatically when
objects go out of scope.
Destructor is indicated with the tilda.
4
Default Assignment
Stack outer_stack;
for (int i =0; i <1000000; i++){
Stack inner_stack;
inner_stack.push(some_data);
inner_stack = outer_stack;
}
outer_stack.top_node
top
entry
middle
entry
bottom
entry
inner_stack.top_node
some_
data
5
Reference Semantics
The problems discussed in this lecture occur because the linked
list implementation of Stacks (and Queues) uses reference
semantics.
Reference semantics refers to the situation where we are
working with addresses (pointers) rather than values.
Value semantics refers to the situation when we are working
with values.
In the linked list version of the Stack class, the only data member
is a pointer (reference semantics). This can cause problems
when it is copied unless we provide functions to deal with them. 6
Overloading the assignment
operator
We create our own Stack function to handle assignments
between stacks:
void Stack::operator = (const Stack &original);
This function will be called when one Stack object is assigned
to another. The following statements are equivalent:
myStack.operator = (yourStack);
myStack = yourStack;
7
Assignment with Stacks
To assign one stack to another one must:
1) Make a copy of the stack contained in the parameter (original).
2) Clear the stack being assigned to.
3) Move the copied data to the stack being assigned to.
8
Implementing the overloaded
assignment operator
void Stack :: operator =(const Stack &original)
//Overload assignment
{
Node *new_top, *new_copy, *original_node;
original_node = original.top_node;
if (original_node == NULL) {
new_top =NULL;
} else {
//Duplicate the linked nodes
new_top = new Node(original_node ->entry);
new_copy = new_top;
while (original_node ->next != NULL){
original_node = original_node ->next ;
new_copy ->next = new Node(original_node ->entry);
new_copy = new_copy ->next;
}
}
while (!empty()) {
//Clean out old Stack entries
pop();
}
top_node = new_top ;
//and replace them with new entries.
}
9
Problems with copying stacks
void destroy_the_stack (Stack copy) {
}
int main() {
Stack vital_data ;
destroy_the_stack(vital_data);
}
vital_data.top_node
top
entry
middle
entry
bottom
entry
copy.top_node
• When the destructor for copy is called, the stack for vital_data is deleted!
10
Steps for Copying a Stack
The copy constructor must perform the following steps:
1) Copy the NULL pointer if the stack to be copied is empty.
2) Copy the first node.
3) Use a loop to copy the other nodes.
11
The Copy Constructor
Stack::Stack(const Stack &original)
//copy constructor
{
Node *new_copy ,*original_node;
original_node = original.top_node;
if (original_node == NULL) {
top_node = NULL;
} else {
//Duplicate the linked nodes.
top_node = new_copy = new Node(original_node ->entry);
while (original_node ->next != NULL){
original_node = original_node ->next;
new_copy ->next = new Node(original_node ->entry);
new_copy = new_copy ->next ;
}
}
}
12
The new Stack specification
class Stack {
public:
//Standard Stack methods
Stack();
bool empty() const;
Error_code push(const Stack_entry &item);
Error_code pop();
Error_code top(Stack_entry &item) const;
//Safety features for linked structures
~Stack();
Stack(const Stack &original);
void operator =(const Stack &original);
protected:
Node *top_node;
};
13