OK making progress here. My question is now related to copy construction and deep-copy. My stack is currently crashing all the time and I have a feeling that it is doing so because the class it is dependent on doesn't allow copy construction and operator overloading. But anyway here is my code (I apologize for the amount of code but it is probably necessary to understand where i am failing):
The dependent class, linked list
#ifndef linkList_H
#define linkList_H
//
// Create an object to represent a Node in the linked list object
// (For now, the objects to be put in the list will be integers)
//
struct Node
{
int number;
Node* next;
Node* prev;
// needs copy constructor?
// needs overloaded assignment operators for copying?
// needs overloaded operators for incrementing and decrementing?
};
//
// Create an object to keep track of all parts in the list
//
class List
{
public:
//
// Contstructor intializes all member data
//
List() : m_size(0), m_listHead(0) {}
//
// methods to return size of list and list head
//
Node* getListHead() const { return m_listHead; }
unsigned getListSize() const { return m_size; }
//
// methods for adding and inserting a new node to the linked list,
// retrieving and deleting a specified node in the list
//
void addNode(int num);
void deleteNode(Node* current);
void insertHead(Node* current);
void insertAfter(Node* current, int newValue);
void insertBefore(Node* current, int newValue);
Node* retrieveNode(unsigned position);
private:
//
// member data consists of an unsigned integer representing
// the list size and a pointer to a Node object representing head
//
Node* m_listHead;
unsigned m_size;
};
#endif
Implementation of linkedList
#include "linkList.h"
#include <iostream>
using namespace std;
//
// Adds a new node to the linked list
//
void List::addNode(int num)
{
Node *newNode = new Node;
newNode->number = num;
newNode->next = m_listHead;
if( m_listHead )
m_listHead->prev = newNode;
m_listHead = newNode;
++m_size;
}
//
// Inserts a node which has already been set to front
// of the list
//
void List::insertHead(Node* current)
{
int value = current->number;
deleteNode(current);
addNode(value);
}
//
// Inserts a node which has already been set before a
// specified location in the list
//
void List::insertBefore(Node* current, int newValue)
{
current = current->prev;
current->number = newValue;
}
//
// Inserts a node which has already been set before a
// specified location in the list
//
void List::insertAfter(Node* current, int newValue)
{
current = current->next;
current->number = newValue;
}
//
// Deletes a node from a specified position in linked list
//
void List::deleteNode(Node* current)
{
--m_size;
if(current == m_listHead)
m_listHead = current->next;
if(current->prev)
current->prev->next = current->next;
if(current->next)
current->next->prev = current->prev;
}
//
// Retrieves a specified node from the list
//
Node* List::retrieveNode(unsigned position)
{
if(position > (m_size-1) || position < 0)
{
cout << "Can't access node; out of list bounds";
cout << endl;
cout << endl;
exit(EXIT_FAILURE);
}
Node* current = m_listHead;
unsigned pos = 0;
while(current != 0 && pos != position)
{
current = current->next;
++pos;
}
return current;
}
Here is the stack class:
#ifndef stack_H
#define stack_H
#include "linkList.h"
class Stack
{
public:
//
// Constructor, copy constructor and destructor to initialize stack
// data, copy data and clear up memory, respectively
//
Stack() : m_top(0), m_stack(new List()) {}
Stack(const Stack &rhs);
~Stack() { delete [] m_stack; }
//
// functionality to determine if stack is empty
//
bool isEmpty();
//
// methods for pushing data on to stack and for
// popping data from the stack
//
void push(int newValue);
int pop();
//
// accessor functions for retrieving the value on top of stack
// and for returning the stack size
//
int getTop() const { return m_top->number; }
int getSize() const { return m_stack->getListSize(); }
//
// overloaded assignment operator for copying stack
//
Stack& operator=(const Stack &rhs);
private:
//
// member data which represent the stack, the top
// of the stack and the size of the stack
//
Node* m_top;
List* m_stack;
};
#endif
And finally, here is the stack implementation
#include "stack.h"
#include <iostream>
using namespace std;
//
// Copy constructor
//
Stack::Stack(const Stack &rhs)
: m_top(rhs.m_top), m_stack(rhs.m_stack)
{
}
//
// if the Top of stack is zero, return true
//
bool Stack::isEmpty()
{
if( m_top == 0 ) return true;
else return false;
}
//
// increment stack pointer, place new value in stack
//
void Stack::push(int newValue)
{
++m_top;
m_top->number = newValue; // crashes on this statement
}
//
// if the stack is empty, throw an error message
//
int Stack::pop()
{
if( isEmpty() )
{
cout << "Error: stack underflow" << endl;
exit(EXIT_FAILURE);
}
--m_top;
return (m_top + 1)->number;
}
Stack& Stack::operator=(const Stack &rhs)
{
if( this != &rhs )
delete [] m_stack;
m_stack = new List();
m_stack = rhs.m_stack;
m_top = rhs.m_top;
return *this;
}
Program crashes after this simple code in the main program:
Stack stack;
stack.push(1);
Again, sorry for the amount of code here. I believe my problem here is that the Node object needs overloaded operators in order to "increment" or "decrement" to create/delete a node when a value is being pushed/popped to the stack. Is this the case? Also, I am not sure if I need a copy constructor or not for the Node object. There could be many more problems here (maybe the algorithms are incorrect? maybe copy construction is incorrect for stack?). Any ideas?
m_topis initialized to 0, so it isnullwhen you try to push it is null and will fail.pop()is also horribly wrong and would crash in an equally spectacular way.