#include using namespace std; // implementation of linked list w/ templates // example w/ list // fns stored w/ class before main // list refers to node, so forward declaration is needed template class node; // template // class list; // template // ostream& operator<< (ostream &, const list &); // overloaded print op. template class list { public: node* head; // ptr to head of list // list(); // default constructor // list(const T[]); // another constructor // ~list(); // destructor // list(const list& in_list); // copy constructor // list& operator=(const list& in_list); // overloaded asgt op // int count_e_iter() const; // iterative traversal // int count_e_recr() const; // recursive traversal list() // default constructor { head = 0; cout << "Called default constructor for list " << *this << endl; } list(const T* in_str) // another constructor { int sub; node* p = 0; node* prev_p; head = 0; for (sub = 0; sub < strlen(in_str); sub++) { prev_p = p; p = new node(in_str[sub], 0); if (sub == 0) head = p; else prev_p -> link = p; } cout << "Called constructor for list at " << *this << endl; } ~list() // destructor { cout << "Called destructor for list at " << this << endl; if (head != 0) // reset list to null reset(); } list(const list& in_list) // copy constructor { node* p; node* q; node* prev_q; cout << "Called copy constructor to copy list at " << &in_list << endl; head = 0; if (in_list.head != 0) { p = in_list.head; while (p != 0) { q = new node(*p); // get new node, copy data members q -> link = 0; // ... zero out new link, if (head == 0) // ... and make someone point to it head = q; else prev_q -> link = q; p = p -> link; prev_q = q; } } cout << "New list is at " << *this << endl; } list& operator=(const list& in_list) // overloaded asgt op { node* p; node* q; node* prev_q; cout << "Called overloaded asgt op from list at " << &in_list << endl; if (this != &in_list) // Make sure not same object { if (head != 0) // free old result reset(); if (in_list.head != 0) { p = in_list.head; // create & fill new list while (p != 0) { q = new node(*p); // get new node, copy data members q -> link = 0; // ... zero out new link, if (head == 0) // ... and make someone point to it head = q; else prev_q -> link = q; p = p -> link; prev_q = q; } } } cout << "Result is at " << *this << endl << endl; return *this; // return ref for chained asgt } int count_e_iter() const { node* p; int count; p = head; count = 0; while (p != 0) { if (p -> item == 'e') count++; p = p -> link; } return count; } int count_e_recr() const { int count = -99; cout << "beginning recursive traversal " << endl; if (head == 0) count = 0; else count = head -> count_e_private(); cout << "ending recursive traversal " << endl << endl; return count; } private: friend ostream& operator<< <>(ostream &, const list &); // overloaded print op. // void reset(); // reset to null void reset() // reset list to null { node* p; node* p_next; if (head != 0) { p = head; while (p != 0) { p_next = p -> link; // get next link while it's still available cout << "Freeing memory at " << p << endl; delete p; p = p_next; } cout << endl; head = 0; } } }; template ostream& operator<< (ostream& ostr, const list& in_list) { node* p; ostr << &in_list << endl; // address of object ostr << "head is " << in_list.head << endl; p = in_list.head; while (p != 0) { ostr << *p << endl; p = p -> link; } return ostr; } template class node { public: T item; // content node* link; // ptr to next node // node(); // default constructor // node(T, node*); // another constructor node() // default constructor { link = 0; cout << "Called default constructor for node " << *this << endl; } node(T in_item, node* in_link) // another constructor { item = in_item; link = in_link; cout << "Called constructor for node " << *this << endl; } private: friend class list; // 'list' fns can see all of node friend ostream& operator<< <>(ostream &, const node &); // overloaded print op. // int count_e_private(); // rec. trav. helper fn int count_e_private() { int count = -99; cout << "entering count_e_private: item = " << item << " count = " << count << endl; if (link == 0) count = 0; else count = link -> count_e_private(); if (item == 'e') count++; cout << "leaving count_e_private: item = " << item << " count = " << count << endl; return count; } }; // *********************************** int main() { char my_string[80] = "i love peeps"; int e_count; // constructor creates dynamic memory list list1(my_string); cout << "list1 is at " << list1 << endl; // iterative traversal e_count = list1.count_e_iter(); cout << "Counting iteratively, there are " << e_count << " e's" << endl; // recursive traversal e_count = list1.count_e_recr(); cout << "Counting recursively, there are " << e_count << " e's" << endl << endl; // testing copy constructor list list2(list1); cout << "list2 is at " << list2 << endl; // testing overloaded asgt op list2 = list1; cout << "list2 is at " << list2 << endl; return 0; } // *********************************** template ostream& operator<< (ostream& ostr, const node& in_node) { ostr << &in_node // address of object << ": " << in_node.item << " " << in_node.link; return ostr; }