⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listr301.cpp

📁 teach yourself C++ in 21 days 第五版
💻 CPP
字号:
 // **************************************************
 //
 // Title:     Week 3 in Review
 //
 // File:      Week3
 //
 // Description:   Provide a template-based linked list
 //                demonstration program with exception handling
 //
 // Classes:    PART - holds part numbers and potentially other
 //                      information about parts. This will be the
 //                      example class for the list to hold
 //                      Note use of operator<< to print the
 //                      information about a part based on its
 //                      runtime type.
 //
 //               Node - acts as a node in a List
 //
 //               List - template-based list which provides the
 //                      mechanisms for a linked list
 //
 //
 // Author:    Jesse Liberty (jl)
 //
 // Developed:   Pentium 200 Pro. 128MB RAM MVC 5.0
 //
 // Target:    Platform independent
 //
 // Rev History:  9/94 - First release (jl)
 //               4/97 - Updated (jl)
 //               9/04  Updated (blj)
 // **************************************************
 #include <iostream>
 using namespace std;
 
 // exception classes
 class Exception {};
 class OutOfMemory :   public Exception{};
 class NullNode :    public Exception{};
 class EmptyList :   public Exception {};
 class BoundsError :   public Exception {};
 
 
 // **************** Part ************
 // Abstract base class of parts
 class Part
 {
   public:
     Part():itsObjectNumber(1) {}
     Part(int ObjectNumber):itsObjectNumber(ObjectNumber){}
     virtual ~Part(){};
     int GetObjectNumber() const { return itsObjectNumber; }
     virtual void Display() const =0;  // must be overridden
 
   private:
     int itsObjectNumber;
 };
 
 // implementation of pure virtual function so that
 // derived classes can chain up
 void Part::Display() const
 {
    cout << "\nPart Number: " << itsObjectNumber << endl;
 }
 
 // this one operator<< will be called for all part objects.
 // It need not be a friend as it does not access private data
 // It calls Display() which uses the required polymorphism
 // We'd like to be able to override this based on the real type
 // of thePart, but C++ does not support contravariance
 ostream& operator<<( ostream& theStream,Part& thePart)
 {
    thePart.Display();  // virtual contravariance!
    return theStream;
 }
 
 // **************** Car Part ************
 class CarPart : public Part
 {
   public:
     CarPart():itsModelYear(94){}
     CarPart(int year, int partNumber);
     int GetModelYear() const { return itsModelYear; }
     virtual void Display() const;
   private:
     int itsModelYear;
 };
 
 CarPart::CarPart(int year, int partNumber):
    itsModelYear(year),
    Part(partNumber)
 {}
 
 void CarPart::Display() const
 {
   Part::Display();
   cout << "Model Year: " << itsModelYear << endl;
 }
 
 // **************** AirPlane Part ************
 class AirPlanePart : public Part
 {
   public:
     AirPlanePart():itsEngineNumber(1){};
     AirPlanePart(int EngineNumber, int PartNumber);
     virtual void Display() const;
     int GetEngineNumber()const { return itsEngineNumber; }
   private:
     int itsEngineNumber;
 };
 
 AirPlanePart::AirPlanePart(int EngineNumber, int PartNumber):
    itsEngineNumber(EngineNumber),
    Part(PartNumber)
 {}
 
 void AirPlanePart::Display() const
 {
    Part::Display();
    cout << "Engine No.: " << itsEngineNumber << endl;
 }
 
 // forward declaration of class List
 template <class T>
 class List;
 
 // ****************  Node ************
 // Generic node, can be added to a list
 // ************************************
 
 template <class T>
 class Node
 {
   public:
     friend class List<T>;
     Node (T*);
     ~Node();
     void SetNext(Node * node) { itsNext = node; }
     Node * GetNext() const;
     T * GetObject() const;
   private:
     T* itsObject;
     Node * itsNext;
 };
 
 // Node Implementations...
 
 template <class T>
 Node<T>::Node(T* pOjbect):
    itsObject(pOjbect),
    itsNext(0)
 {}
 
 template <class T>
 Node<T>::~Node()
 {
    delete itsObject;
    itsObject = 0;
    delete itsNext;
    itsNext = 0;
 }
 
 // Returns NULL if no next Node
 template <class T>
 Node<T> * Node<T>::GetNext() const
 {
    return itsNext;
 }
 
 template <class T>
 T * Node<T>::GetObject() const
 {
    if (itsObject)
       return itsObject;
    else
       throw NullNode();
 }
 
 // ****************  List ************
 // Generic list template
 // Works with any numbered object
 // ***********************************
 template <class T>
 class List
 {
   public:
     List();
     ~List();
 
     T*        Find(int & position, int ObjectNumber)  const;
     T*      GetFirst() const;
     void      Insert(T *);
     T*      operator[](int) const;
     int      GetCount() const { return itsCount; }
   private:
     Node<T> * pHead;
     int      itsCount;
 };
 
 // Implementations for Lists...
 template <class T>
 List<T>::List():
    pHead(0),
    itsCount(0)
 {}
 
 template <class T>
 List<T>::~List()
 {
    delete pHead;
 }
 
 template <class T>
 T*   List<T>::GetFirst() const
 {
    if (pHead)
       return pHead->itsObject;
    else
       throw EmptyList();
 }
 
 template <class T>
 T *  List<T>::operator[](int offSet) const
 {
    Node<T>* pNode = pHead;
 
    if (!pHead)
       throw EmptyList();
 
    if (offSet > itsCount)
       throw BoundsError();
 
    for (int i=0;i<offSet; i++)
       pNode = pNode->itsNext;
 
    return   pNode->itsObject;
 }
 
 // find a given object in list based on its unique number (id)
 template <class T>
 T*   List<T>::Find(int & position, int ObjectNumber)  const
 {
    Node<T> * pNode = 0;
    for (pNode = pHead, position = 0;
         pNode!=NULL;
         pNode = pNode->itsNext, position++)
    {
       if (pNode->itsObject->GetObjectNumber() == ObjectNumber)
         break;
    }
    if (pNode == NULL)
       return NULL;
    else
       return pNode->itsObject;
 }
 
 // insert if the number of the object is unique
 template <class T>
 void List<T>::Insert(T* pObject)
 {
    Node<T> * pNode = new Node<T>(pObject);
    Node<T> * pCurrent = pHead;
    Node<T> * pNext = 0;
 
    int New =  pObject->GetObjectNumber();
    int Next = 0;
    itsCount++;
 
    if (!pHead)
    {
       pHead = pNode;
       return;
    }
 
    // if this one is smaller than head
    // this one is the new head
    if (pHead->itsObject->GetObjectNumber() > New)
    {
       pNode->itsNext = pHead;
       pHead = pNode;
       return;
    }
 
    for (;;)
    {
       // if there is no next, append this new one
       if (!pCurrent->itsNext)
       {
         pCurrent->itsNext = pNode;
         return;
       }
 
       // if this goes after this one and before the next
       // then insert it here, otherwise get the next
       pNext = pCurrent->itsNext;
       Next = pNext->itsObject->GetObjectNumber();
       if (Next > New)
       {
         pCurrent->itsNext = pNode;
         pNode->itsNext = pNext;
         return;
       }
       pCurrent = pNext;
    }
 }
 
 
 int main()
 {
    List<Part> theList;
    int choice = 99;
    int ObjectNumber;
    int value;
    Part * pPart;
    while (choice != 0)
    {
       cout << "(0)Quit (1)Car (2)Plane: ";
       cin >> choice;
 
       if (choice != 0)
       {  
 
          cout << "New PartNumber?: ";
          cin >>  ObjectNumber;
 
          if (choice == 1)
          {
            cout << "Model Year?: ";
            cin >> value;
            try
            {
              pPart = new CarPart(value,ObjectNumber);
            }
            catch (OutOfMemory)
            {
              cout << "Not enough memory; Exiting..." << endl;
              return 1;
            }
          }
          else
          {
            cout << "Engine Number?: ";
            cin >> value;
            try
            {
              pPart = new AirPlanePart(value,ObjectNumber);
            }
            catch (OutOfMemory)
            {
              cout << "Not enough memory; Exiting..." << endl;
              return 1;
            }
          }
          try
          {
            theList.Insert(pPart);
          }
          catch (NullNode)
          {
            cout << "The list is broken, and the node is null!" << endl;
            return 1;
          }
          catch (EmptyList)
          {
            cout << "The list is empty!" << endl;
            return 1;
          }
       }
    }
    try
    {
       for (int i = 0; i < theList.GetCount(); i++ )
         cout << *(theList[i]);
    }
       catch (NullNode)
       {
         cout << "The list is broken, and the node is null!" << endl;
         return 1;
       }
       catch (EmptyList)
       {
         cout << "The list is empty!" << endl;
         return 1;
       }
       catch (BoundsError)
       {
         cout << "Tried to read beyond the end of the list!" << endl;
         return 1;
       }
    return 0;
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -