I'm trying to write a class representing a Stack object in C++ using templates. This stack object will hold as data 'EToll' objects, which represent cars in the real world.
This is for a university task, and some restrictions have been placed on me. They are as follows:
The Stack must:
- be built by 'wrappering' around a LinkedList (essentially I've just included a "LinkedList" as a private member for stack and built it's functions based on functions inside a LinkedList class I wrote).
- printing or removing elements from the stack must be done via methods within the stack (eg push(), pop(), etc.) and cannot just call print or remove methods from LinkedList.
The stack cannot:
- use keywords 'struct' or 'friend'
- reveal internal structure (such as by returning 'data' publicly)
With that out of the way, let me explain what I'm trying to do. I want to output the entire contents of a stack object by overloading the stream insertion operator (ie '<<'). I'm aware the way Stacks are built make this rather inconvenient, but this is one of the requirements of the task. This is my code for the '<<' operator overload:
template <typename T>
ostream& operator << (ostream& out, LStack<T>& LS)
{
if (LS.isEmpty())
{
out << "List is empty.";
} else
{
LStack<T> LScopy;
LScopy = LS.copy(LS); //ensures original input LS remains unmodified
while (!(LScopy.isEmpty()))
{
out << "(";
out << LScopy.peek().get_licence();
out << ", ";
out << LScopy.peek().get_charge();
out << ") ";
LScopy.pop(); //continues the traversal of LScopy
}
//delete LS copy here to prevent memory leak
return out;
}
}
I need a copy function to ensure the input 'LS' doesn't get modified within the '<<' overload. I have next to no experience with copy functions or templates, so I am lost as to how to make my copy function. Other threads trying to achieve similar things (eg C++ Creating a copy constructor for stack class ) have not worked. memcpy has not worked either. Here is what I've tried to do with my copy function:
//returns a copy of parameter 'src' as a LinkedList<T>&
template <typename T>
LStack<T>& LStack<T>::copy(LStack<T>& src)
{
LStack<T>* srcCopy = new LStack<T>();
//copying contents of src to srcCopy
memcpy(srcCopy, src, sizeof(src));
//returning the copied LStack
return srcCopy;
}
Here's the basic code for my stack class (haven't included full thing for sake of brevity):
//start macroguard
#ifndef LSTACK_H
#define LSTACK_H
#include "LinkedList.h"
#include <x> <y> <z> etc ...
template <typename T>
class LStack
{
public:
//constructor:
LStack();
//Destructor:
~LStack();
//push - adds item to top of stack
void push(T& obj);
//copy function - not working at present
LStack<T>& copy(LStack<T>& src);
//pop - removes and returns item at top of Stack. If
//stack is empty, do nothing
T pop();
//peek - returns item at top of stack
T& peek();
//size - returns number of items in the stack
int size() const;
//isEmpty - indicates if the stack has 0 or >0 items
bool isEmpty();
private:
LinkedList<T> data;
};
//'<<' operator overload - prints all items in stack
template <typename T>
ostream& operator << (ostream&, LStack<T>& LS);
#include "LStack.hpp"
#endif //end of macroguard
Here's the basic code for my LinkedList class:
//start macroguard
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h"
#include <x> <y> <z> etc...
template <typename T>
class LinkedList
{
public:
//Constructor:
LinkedList();
//Destructor:
~LinkedList();
//addToHead - adds an item to head of list
void addToHead(T& item);
//addToTail - adds an item to tail of list
void addToTail(T& item);
//removeNode - calls relevant function if parameter
//'nodeToRemove' was head or tail. otherwise, removes
//an internal node from the list.
void removeNode(Node<T>* nodeToRemove);
//removeFromHead - removes an item from head of list
void removeFromHead();
//removeFromTail - removes an item from tail of list
void removeFromTail();
//length - returns number of Nodes in list
int length();
//isEmpty - indicates whether list has 0 or >0 items
bool isEmpty();
//getHead - returns 'data' value of list's head
T& getHead();
//getTail - returns 'data' value of list's tail
T& getTail();
//getCurrentData - returns 'data' value of list's
//'current' pointer
T& getCurrentData();
//moveCurrentForward - moves 'current' pointer to
//next node
void moveCurrentForward();
//moveCurrentBackward - moves 'current' pointer to
//previous node
void moveCurrentBackward();
//moveCurrentToHead - moves 'current' pointer to
//list's head
void moveCurrentToHead();
//moveCurrentToTail - moves 'current' pointer to
//list's tail
void moveCurrentToTail();
private:
Node<T>* head;
Node<T>* tail;
Node<T>* current; //used when traversing list
};
template <typename T>
ostream& operator << (ostream& out, LinkedList<T>& LL);
#include "LinkedList.hpp"
#endif //end of macroguard
Finally the basic code for my Node class:
#ifndef NODE_H
#define NODE_H
#include "EToll.h"
#include <x> <y> <z> etc....
template <typename T>
class Node
{
public:
//Constructors
Node(); //default
//i = data item, n = next, p = prev
Node(const T& i, Node* n, Node* p); //detailed constructor
//destructor
~Node();
//set_next - sets the next value of Node
void set_next(Node* next_ptr);
//set_prev - same as above
//set_data - sets the data value of Node
void set_data(const T& new_data);
//get_next - returns the next value of Node
//get_prev - same as above
//get_data - returns the data value of Node
T& get_data();
private:
Node* next;
Node* prev;
T data;
};
#include "Node.hpp"
#endif
Final notes:
- Please forgive any glaring issues like memory leaks or unoptimised programming decisions. I am a novice with Data Structures. Also I am new to C++ - I come from Java where everything is much simpler. My goal right now is "make sure everything just works now and fix issues later".
- If you need any extra code or explanation why I've done certain things, ask and I will provide it to you.
Thanks a lot for any help.