20-CS-122-001 Computer Science II Spring 2012
Simple List - Use compare function so List Need Not Know A

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

Prev      Next      Lectures      Source

#include <iostream>
using namespace std;

// Use cmp function to eliminate the need for class List to know class A.
// Unfortunately, to display a List object we still need to know class A.
// Also, List class is still not general since it compares against an int.
class A {
   friend ostream & operator<<(ostream &out, A *a);
   friend bool cmp (void *, int);
   int number;

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

// Added - application has no trouble with this because it knows A since
//   class A was built in the application.
bool cmp (void *obj, int number) {  return ((A*)obj)->number == number;  }

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

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 *, int);   // Added

public:
   List (bool (*cmpfunc)(void *, int)) { 
      head = NULL; 
      this->cmpfunc = cmpfunc;     // Added
   }
   
   void operator+=(void *obj) {  head = new Cell(obj, head);  }
   
   void operator-=(int number) {
      if (cmpfunc(head->item, number)) { // 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, number)) { // No dependence on class A
	    Cell *temp = ptr->next;  
	    ptr->next = ptr->next->next;
	    delete temp;             
	    return;
	 }
      }
   }
};

// Still need to know class A here - this should be a library function
ostream &operator<<(ostream &out, List &lst) {
   for (Cell *ptr = lst.head ; ptr != NULL ; ptr=ptr->next) 
      out << ((A*)ptr->item) << " ";
   return out;
}

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