📄 listr301.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 + -