20-CS-122-001 Computer Science II Spring 2012
Simple List - Use display function so List can be put into library

Virtual functions, classes, inheritance, lists, queues, stacks, applications

Prev      Next      Lectures      Source

#include <iostream>
using namespace std;

// Only problems left: 1) cmp function is not general enough for class List
// to be put into a library (requires an int).  Solution is to change the 
// prototype for the compare function and to add a display function.
// 2) still need to know about class A to display a List.  Solution is
// to add a display function.
class A {
   friend ostream & operator<<(ostream &out, A *a);
   friend bool cmp (void *, void *);    // Changed
   friend void disp (void *);           // Added
   int number;

public:
   A (int number) { this->number = number; }
};

// Changed - very general comparison
bool cmp (void *obj, void *what) { return ((A*)obj)->number == *(int *)what; }
// Added
void disp (void *obj) {  cout << ((A*)obj)->number; }

ostream & operator<<(ostream &out, A *a) {
   out << a->number;
   return out;
}

/***   Beginning of section that can be libraried   ***/

class Cell {
   friend class List;
   friend ostream &operator<<(ostream &, List &);
   void *item;
   Cell *next;
   Cell (void *item, Cell *next) { this->item = item; this->next = next; }   
};

class List {
   friend ostream & operator<<(ostream &, List &);
   Cell *head;
   bool (*cmpfunc)(void *, void *);   // Changed
   void (*dispfunc)(void *);          // Added

public:
   List (bool (*cmpfunc)(void *, void *), void (*dispfunc)(void *)) {// Changed
      head = NULL; 
      this->cmpfunc = cmpfunc;
      this->dispfunc = dispfunc;
   }
   
   void operator+=(A *obj) {  head = new Cell(obj, head);  }
   
   void operator-=(void *what) {       // Changed
      if (cmpfunc(head->item, what)) { // No dependence on class A
	 Cell *temp = head;    
	 head = head->next;
	 delete temp;          
	 return;
      }
      for (Cell *ptr=head ; ptr->next != NULL ; ptr=ptr->next) {
	 if (cmpfunc(ptr->next->item, what)) { // No dependence on class A
	    Cell *temp = ptr->next;  
	    ptr->next = ptr->next->next;
	    delete temp;             
	    return;
	 }
      }
   }
};

ostream &operator<<(ostream &out, List &lst) {
   for (Cell *ptr = lst.head ; ptr != NULL ; ptr=ptr->next) {
      lst.dispfunc(ptr->item); 
      out << " ";
   }
   return out;
}

/***   End of section that can be libraried   ***/

int main () {
   int number = 42;
   List lst(cmp, disp);
   lst += new A(23);
   lst += new A(42);
   lst += new A(16);
   lst += new A(67);
   cout << lst << "\n";
   lst -= new int(16);
   cout << lst << "\n";
   lst += new A(16);
   cout << lst << "\n";
   lst -= &number;
   cout << lst << "\n";
}