Selected C Example 18

 <  Free Open Study  >  

Selected C++ Example #18

 // Example #18  // This example code shows the attempt to implement three // different lists (meal lists, airplane lists, and dog lists) // with one implementation of the list code. The general approach // is to use C++ templates to capture the common structure // that all LinkedLists share. The template is then used to // generate the three different lists. The advantage of templates // over weakened type checking via inheritance (Example #17) is // that mistakes of flying dogs off runways cannot occur (due to // the maintenance of strong type checking by templates). The // disadvantage is that we pay for the class/method code for each // new data type that wishes to have a list instantiation. #include <iostream.h> #include <new.h> // The derived classes Dog, Meal, and Airplane are only // skeleton classes, to simplify their implementation. class Dog { public:      void bark();      void bite();      void print(ostream& o = cout); }; void Dog::bark() {      cout << ''Bow Wow\n''; } void Dog::bite() {      cout << ''Ouch!!!\n''; } void Dog::print(ostream& o) {      o << ''I am a dog!\n''; } classMeal { public:      void eat();      void print(ostream& o = cout); }; void Meal::eat() {   cout << ''Crunch ... Munch ... Crunch ...\n''; } void Meal::print(ostream& o) {      o << ''I'm a meal\n''; } class Airplane { public:      void fly();      void print(ostream&o = cout); }; void Airplane::fly() {      cout << ''Va-a-a--room!!!\n''; } void Airplane::print(ostream& o) {      o << ''I'm an airplane!\n''; } // Borland wouldn' t accept nested templates, so the Node class is // placed outside the scope of the LinkedList. template <class DATUM> struct Node {      DATUM data;      Node* next; public:      Node(DATUM&); }; template <class DATUM> class LinkedList{       Node<DATUM>* head;       int len; public:      LinkedList();      ~LinkedList();      int insert(DATUM&);      DATUM remove();      void traverse() const;      int length(); }; template <class DATUM> Node<DATUM>::Node(DATUM& new_item) {      data = new_item;      next = NULL; } template <class DATUM> LinkedList<DATUM>::LinkedList() {      head = NULL;      len = 0; } template <class DATUM> LinkedList<DATUM>::~LinkedList() {      Node<DATUM>* temp;      while (head != NULL) {          temp = head;          head = head->next;          delete temp;      } } template <class DATUM> int LinkedList<DATUM>::insert(DATUM& new_item) {      Node<DATUM>* temp = head;      if (temp == NULL) {           head = new Node<DATUM>(new_item);     }      else {           while (temp->next != NULL) {                      temp = temp->next;           }           temp->next = new Node<DATUM>(new_item);      }      return(++len); } template <class DATUM> DATUM LinkedList<DATUM>::remove() {      Node<DATUM>* temp = head;      static DATUM bad_item;      DATUM retval;      if (temp == NULL) {           return(bad_item);      }      else {           retval = head->data;           head = head->next;           len--;           delete temp;           return(retval);      } } // Notice that the traverse method sends a message to the // data in each node to print itself. This sets up a requirement // that any data type that wants to be in a LinkedList needs // a print method. An even more important consideration is // the fact that the syntax is different if DATUM is a pointer // or nonpointer. Nonpointers would use a dot, and not // an arrow, operator. The template requires its DATUM to be // a pointer (in this example), and that the DATUM possess a // print method. template <class DATUM> void LinkedList<DATUM>::traverse() const {      Node<DATUM>* temp = head;      cout << ''(\n'';      while (temp != NULL) {          temp->data->print();          cout << ''\n'';          temp = temp->next;      }      cout << '')\n\n''; } template <class DATUM> int LinkedList<DATUM>::length() {      return(len); } void main() {      LinkedList<Meal*> MealList;      LinkedList<Airplane*> AirplaneList;      LinkedList<Dog*> DogList; // The following template expansion would generate errors due to // the traverse method requiring a pointer data type (or at least // a data type that supports the ''->'' operator). // //     LinkedList<Dog> x; //              Meal *meal1 = new Meal, *meal2 = new Meal, *meal3 = new Meal;       Dog *dog1 = new Dog, *dog2 = new Dog, *dog3 = new Dog;       Airplane *air1 = new Airplane, *air2 = new Airplane, *air3 =                        new Airplane;                         // At first glance everything seems to work nicely        MealList.insert(meall);       MealList.insert(meal2);       MealList.insert(meal3);       Meal* aMeal = (Meal*) MealList. remove();       aMeal->eat();       char c;       cin >> c;       AirplaneList.insert(air1);       AirplaneList.insert(air2);       AirplaneList.insert(air3);       DogList.insert(dog1);       DogList.insert(dog2);       DogList.insert(dog3);       MealList.traverse();       AirplaneList.traverse();       DogList.traverse();       cin >> c; // The following line of code would generate compiler errors due to // the preservation of strong type checking by the C++ template // mechanism. // //         AirplaneList.insert(dog2);       delete meal1;       delete meal2;       delete meal3;       delete dog1;       delete dog2;       delete dog3;       delete air1;       delete air2;       delete air3; } 
 <  Free Open Study  >  


Object-Oriented Design Heuristics
Object-Oriented Design Heuristics (paperback)
ISBN: 0321774965
EAN: 2147483647
Year: 1996
Pages: 180

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net