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

📄 list1607.cpp

📁 teach yourself C++ in 21 days 第五版
💻 CPP
字号:
//Listing 16.7 Friend Class Illustrated

#include <iostream>
using namespace std;

// **************** Part ************

// Abstract base class of parts
class Part
{
  public:
    Part():itsPartNumber(1) {}
    Part(int PartNumber):
    itsPartNumber(PartNumber){}
    virtual ~Part(){}
    int GetPartNumber() const
      { return itsPartNumber; }
    virtual void Display() const =0;
  private:
    int itsPartNumber;
};

// implementation of pure virtual function so that
// derived classes can chain up
void Part::Display() const
{
   cout << "\nPart Number: ";
   cout << itsPartNumber << endl;
}

// **************** Car Part ************

class CarPart : public Part
{
  public:
    CarPart():itsModelYear(94){}
    CarPart(int year, int partNumber);
    virtual void Display() const
    {
       Part::Display();
       cout << "Model Year: ";
       cout << itsModelYear << endl;
    }
  private:
    int itsModelYear;
};

CarPart::CarPart(int year, int partNumber):
   itsModelYear(year),
   Part(partNumber)
{}


// **************** AirPlane Part ************

class AirPlanePart : public Part
{
  public:
    AirPlanePart():itsEngineNumber(1){};
    AirPlanePart(int EngineNumber, int PartNumber);
    virtual void Display() const
    {
       Part::Display();
       cout << "Engine No.: ";
       cout << itsEngineNumber << endl;
    }
  private:
    int itsEngineNumber;
};

AirPlanePart::AirPlanePart(int EngineNumber, int PartNumber):
   itsEngineNumber(EngineNumber),
   Part(PartNumber)
{}

// **************** Part Node ************
class PartNode
{
  public:
    friend class PartsList;
    PartNode (Part*);
    ~PartNode();
    void SetNext(PartNode * node)
       { itsNext = node; }
    PartNode * GetNext() const;
    Part * GetPart() const;
  private:
    Part *itsPart;
    PartNode * itsNext;
};


PartNode::PartNode(Part* pPart):
   itsPart(pPart),
   itsNext(0)
{}

PartNode::~PartNode()
{
    delete itsPart;
   itsPart = 0;
   delete itsNext;
   itsNext = 0;
}

// Returns NULL if no next PartNode
PartNode * PartNode::GetNext() const
{
   return itsNext;
}

Part * PartNode::GetPart() const
{
   if (itsPart)
      return itsPart;
   else
      return NULL; //error
}


// **************** Part List ************
class PartsList
{
  public:
    PartsList();
    ~PartsList();
    // needs copy constructor and operator equals!
    void     Iterate(void (Part::*f)()const) const;
    Part*    Find(int & position, int PartNumber) const;
    Part*    GetFirst() const;
    void     Insert(Part *);
    Part*    operator[](int) const;
    int      GetCount() const { return itsCount; }
    static   PartsList& GetGlobalPartsList()
    {
       return  GlobalPartsList;
   }
  private:
    PartNode * pHead;
    int itsCount;
    static PartsList GlobalPartsList;
};

PartsList PartsList::GlobalPartsList;

// Implementations for Lists...

PartsList::PartsList():
   pHead(0),
   itsCount(0)
{}

PartsList::~PartsList()
{
   delete pHead;
}

Part*   PartsList::GetFirst() const
{
   if (pHead)
      return pHead->itsPart;
   else
      return NULL;  // error catch here
}

Part * PartsList::operator[](int offSet) const
{
   PartNode* pNode = pHead;

   if (!pHead)
      return NULL; // error catch here

   if (offSet > itsCount)
      return NULL; // error

   for (int i=0;i<offSet; i++)
      pNode = pNode->itsNext;

   return   pNode->itsPart;
}

Part* PartsList::Find(int & position, int PartNumber) const
{
   PartNode * pNode = 0;
   for (pNode = pHead, position = 0;
      pNode!=NULL;
   pNode = pNode->itsNext, position++)
   {
      if (pNode->itsPart->GetPartNumber() == PartNumber)
         break;
   }
   if (pNode == NULL)
      return NULL;
   else
      return pNode->itsPart;
}

void PartsList::Iterate(void (Part::*func)()const) const
{
   if (!pHead)
      return;
   PartNode* pNode = pHead;
   do
      (pNode->itsPart->*func)();
   while (pNode = pNode->itsNext);
}

void PartsList::Insert(Part* pPart)
{
   PartNode * pNode = new PartNode(pPart);
   PartNode * pCurrent = pHead;
   PartNode * pNext = 0;

   int New =  pPart->GetPartNumber();
   int Next = 0;
   itsCount++;

   if (!pHead)
   {
      pHead = pNode;
      return;
   }

   // if this one is smaller than head
   // this one is the new head
   if (pHead->itsPart->GetPartNumber() > 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->itsPart->GetPartNumber();
      if (Next > New)
      {
         pCurrent->itsNext = pNode;
         pNode->itsNext = pNext;
         return;
      }
      pCurrent = pNext;
   }
}

class PartsCatalog : private PartsList
{
  public:
    void Insert(Part *);
    int Exists(int PartNumber);
    Part * Get(int PartNumber);
    operator+(const PartsCatalog &);
    void ShowAll() { Iterate(Part::Display); }
  private:
};

void PartsCatalog::Insert(Part * newPart)
{
   int partNumber =  newPart->GetPartNumber();
   int offset;

   if (!Find(offset, partNumber))
      PartsList::Insert(newPart);
   else
   {
      cout << partNumber << " was the ";
      switch (offset)
      {
         case 0:  cout << "first "; break;
         case 1:  cout << "second "; break;
         case 2:  cout << "third "; break;
         default: cout << offset+1 << "th ";
      }
      cout << "entry. Rejected!" << endl;
   }
}

int PartsCatalog::Exists(int PartNumber)
{
   int offset;
   Find(offset,PartNumber);
   return offset;
}

Part * PartsCatalog::Get(int PartNumber)
{
   int offset;
   return (Find(offset, PartNumber));
}

int main()
{
   PartsCatalog pc;
   Part * pPart = 0;
   int PartNumber;
   int value;
   int choice = 99;

   while (choice != 0)
   {
      cout << "(0)Quit (1)Car (2)Plane: ";
      cin >> choice;

      if (choice != 0)
       {
         cout << "New PartNumber?: ";
         cin >>  PartNumber;

         if (choice == 1)
         {
            cout << "Model Year?: ";
            cin >> value;
            pPart = new CarPart(value,PartNumber);
         }
         else
         {
            cout << "Engine Number?: ";
            cin >> value;
            pPart = new AirPlanePart(value,PartNumber);
          }
         pc.Insert(pPart);
      }
   }
   pc.ShowAll();
   return 0;
}

⌨️ 快捷键说明

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