#include <iostream>
usingnamespace std;
template <typename T>
class list {
// ostream & operator<<(ostream & out, const list<T> &);
//ostream & operator<<( const list<T>& list)
//{
//node *p;
//int num;
//for(p = list.first; p != 0; p = p -> next)
//std::cout << p -> num;
//return p;
//}
friend std::ostream& operator << (std::ostream& out , list<T>& obj)
{
std::string separator = "";
for (node* n = obj.first; n != NULL; n = n->next)
{
out << separator;
separator = ", ";
out << n->value;
}
//return out << "]";
}
public:
list(); // constructor
list(const list &l); // copy constructor
list &operator=(const list &l); // assignment operator
~list(); // destructor
// Returns number of elements in the list
unsigned size();
// Returns true if the list is empty, false otherwise.
bool isEmpty() const;
// Inserts element to front of list
void insertFront(const T &val);
// Inserts element to the end of list
void insertBack(const T &val);
// Returns the values of the front element in the list
T front();
// Returns the value of the back element of the list.
T back();
// Deletes the front element of the list and returns its value
void removeFront();
// Deletes the back element of the list and returns its value
void removeBack();
// Prints each element of the list in order
void printForward();
// Prints each element of the list in reverse order
void printReverse();
private:
struct node {
node *next;
node *prev;
T value;
};
node *first; // The pointer to the first node
node *last; // The pointer to the last node
unsigned length; // holds number of elements in the list
// Initializes empty list
void createEmpty();
// Removes all of the elements in the list
void removeAll();
// Makes copy of all of the elements in the list
void copyAll(const list &l);
};
template <typename T>
void list<T>::createEmpty() {
first = NULL;
last = NULL;
length = 0;
}
template <typename T>
void list<T>::removeAll() {
while (!isEmpty()) {
removeFront();
}
}
template <typename T>
void list<T>::copyAll(const list &l) {
node *iterator = l.first;
while (iterator) {
T obj = iterator->value;
insertBack(obj);
iterator = iterator->next;
}
}
template <typename T>
unsigned list<T>::size() {
return length;
}
template <typename T>
bool list<T>::isEmpty() const{
return (first == NULL && last == NULL);
}
template <typename T>
void list<T>::insertFront(const T &val) {
length++;
node *newNode = new node;
new (&(newNode->value)) T(val);
newNode->next = first;
newNode->prev = NULL;
if (isEmpty()) first = last = newNode;
else {
first->prev = newNode;
first = newNode;
}
}
template <typename T>
void list<T>::insertBack(const T &val) {
length++;
node *newNode = new node;
new (&(newNode->value)) T(val);
newNode->next = NULL;
newNode->prev = last;
if (isEmpty()) first = last = newNode;
else {
last->next = newNode;
last = newNode;
}
}
template <typename T>
T list<T>::front() {
return first->value;
}
template <typename T>
T list<T>::back() {
return last->value;
}
template <typename T>
void list<T>::removeFront() {
if (isEmpty()) return;
length--;
node *removedNode = first;
first = first->next;
if (first) first->prev = NULL;
else first = last = NULL;
delete removedNode;
return;
}
template <typename T>
void list<T>::removeBack() {
if (isEmpty()) return;
length--;
node *removedNode = last;
last = last->prev;
if (last) last->next = NULL;
else first = last = NULL;
delete removedNode;
return;
}
template <typename T>
list<T>::list() {
createEmpty();
}
template <typename T>
list<T>::list(const list &l) {
createEmpty();
copyAll(l);
return;
}
template <typename T>
list<T>& list<T>::operator= (const list &l)
{
if (this != &l) {
removeAll();
copyAll(l);
}
return *this;
}
template <typename T>
list<T>::~list() {
removeAll();
}
template <typename T>
void list<T>::printForward() {
if (isEmpty()) {
std::cout << "List is empty\n";
return;
}
node *head = first;
while (head) {
std::cout << head->value << " ";
head = head->next;
}
std::cout << "\n";
}
template <typename T>
void list<T>::printReverse() {
if (isEmpty()) {
std::cout << "List is empty\n";
return;
}
node *tail = last;
while (tail) {
std::cout << tail->value << " ";
tail = tail->prev;
}
std::cout << "\n";
}
#include <iostream>
usingnamespace std;
int main()
{
list<int> list1, list2;
int num;
std::cout<<"Enter integers ending with -999"<<endl;
cin>> num;
while(num != -999)
{
list1.insertFront(num);
cin >> num;
}
std::cout<<endl;
std::cout<<"List 1: " <<list1 << endl;
list2 = list1; //test the assignment operator;
std::cout <<"List 2: " << list2 <<endl;
std::cout<<"Enter the number to be deleted: ";
cin>> num;
std::cout<< endl;
list2.removeFront();
std::cout<<"After deleting the node, ";
std::cout<<"List 2: "<<endl <<list2;
std::cout<<endl;
return 0;
}
It bombs out before I can copy the list and test the delete operation
I believe you just have to return out; on line 28.
Compiler warnings often find errors like this for you. GCC with -Wall tells me that the function has no return value when it is supposed to.
In C++ we use nullptr, not NULL, for dealing with pointers that point to nothing. I'm not the right person to explain the details of why, but perhaps this will help explain:
node *newNode = new node;
new (&(newNode->value)) T(val); // gratuitous use of placement-new
newNode->next = first;
newNode->prev = NULL;
Instead, make a constructor for node and use it:
1 2 3 4 5 6 7 8 9 10 11
struct Node {
Node* next;
Node* prev;
T value;
Node(T value, Node* next, Node* prev)
: next(next), prev(prev), value(value) {}
};
// Use it like this instead of those other 4 lines:
node *newNode = new node(val, first, nullptr);