Phones1.cpp

Download this source file



// Phones1.cpp - Example of simple inheritance without polymorphism.
// From an idea of Coplein's "Advanced C++ Styles and Idioms", 1992,
// page 93.  Note many details have been omitted for the sake of clarity.
//
// Written by Wayne Pollock, Tampa Florida USA, 2000.

enum PhoneType ( POTS, ISDN, OPERATOR, PRINCESS, OTHER );

class Telephone
{
public:
   PhoneType phone_type () const { return phone_type_val; }
   void ring ();
   bool isOnHook ();
   bool isTalking ();
   bool isDialing ();
   LineNumber get_extension ();
   ~Telephone ();

protected:
   Telephone ();  // Trick so only derived classes can invoke the constructor.
                  // (A poor-man's abstract class; there is a better way!)
   LineNumber extension;
   Phonetype phone_type_val;
};

class POTSPhone : public Telephone  // POTS = Plain Old Telephone Service
{
public:
   POTSPhone () : phone_type_val(POTS) { ... }
   POTSPhone ( const POTSPhone & );
   ~POTSPhone ();
   ...

private:
   Frame frame_number;  // these members relate to details of a phone's
   Rack rack_number;    // wiring, location, and connections.
   Pair pair_number;
};

class ISDNPhone : public Telephone  // Integrated Services digital Network
{
public:
   ISDNPhone () : phone_type_val(ISDN) { ... }
   ISDNPhone ( const ISDNPhone & ) : phone_type_val(ISDN);
   ~ISDNPhone ();
   void sendBPacket ();
   void sendDPacket ();

private:
   Channel b1, b2, d;  // Standard residential ISDN has 3 channels.
};

class OperatorPhone : public ISDNPhone   // Note: inherits from ISDNPhone.
{
public:
   OperatorPhone () : phone_val_type(OPERATOR) { ... }
   OperatorPhone ( const OperatorPhone & ) : phone_type_val(OPERATOR) { ... }
   ~OperatorPhone ();
   void ring ();  // Special ringing needed for operator.
   ...
};

class PrincessPhone : public POTSPhone  // A kind of POTSPhone.
{ ... };

void ring_phones ( Telephone* phone_list [] )
{
   for ( Telephone* p = phone_list; p; ++p )  // End of list marked with NULL
      // Using p->ring() would invoke Telephone::ring()
      switch ( p->phone_type() )
      {
         case POTS:  ( (POTSPhone *) p )->ring();  break;
         case ISDN:  ( (ISDNPhone *) p )->ring();  break;
         case Operator:  ( (OperatorPhone *) p )->ring();  break;
	 ...
	 default: error( "unknown Phone Type!" );
      }
}

int main ()
{
   Telephone* phone_array[10];
   int i = 0;
   phone_array[i++] = new POTSPhone( "5384" );
   phone_array[i++] = new ISDNPhone( "1050" );
   phone_array[i++] = new OperatorPhone( "0" );
   phone_array[i++] = new POTSPhone( "5385" );
   ...
   phone_array[i++] = NULL;
   ring_phones( phone_array );
   ...
   delete_phones( phone_array ); // This function is similar to ring_phones().
   return 0;
}

Phones2.cpp

Download this source file



// Phones2.cpp - Example of simple inheritance *with* polymorphism.
// From an idea of Coplein's "Advanced C++ Styles and Idioms", 1992,
// page 93.  Note many details have been omitted for the sake of clarity.
//
// Written by Wayne Pollock, Tampa Florida USA, 2000.

class Telephone
{
public:
   virtual void ring ();
   virtual bool isOnHook ();
   virtual bool isTalking ();
   virtual bool isDialing ();
   LineNumber get_extension ();
   virtual ~Telephone ();

protected:
   Telephone ();  // Trick so only derived classes can invoke the constructor.
                  // (A poor-man's abstract class; See 3rd version for a
                  // better way!)
   LineNumber extension;
};

class POTSPhone : public Telephone  // POTS = Plain Old Telephone Service
{ ...  };

class ISDNPhone : public Telephone  // Integrated Services digital Network
{ ...  };

class OperatorPhone : public ISDNPhone   // Note: inherits from ISDNPhone.
{
   void ring () { ... }
   ...
};

class PrincessPhone : public POTSPhone  // A kind of POTSPhone.
{ ... };

void ring_phones ( Telephone* phone_list [] )
{
   for ( Telephone* p = phone_list; p; ++p )  // End of list marked with NULL
      p->ring();
}

int main ()
{
   Telephone* phone_array[10];
   int i = 0;
   phone_array[i++] = new POTSPhone( "5384" );
   phone_array[i++] = new ISDNPhone( "1050" );
   phone_array[i++] = new OperatorPhone( "0" );
   phone_array[i++] = new POTSPhone( "5385" );
   ...
   phone_array[i++] = NULL;
   ring_phones( phone_array );
   ...
   delete phone_array[0];  // Note correct destructor is called!
   ...
   return 0;
}

Phones3.cpp

Download this source file



// Phones3.cpp - Example of inheritance with polymorphism, abstract classes.
// From an idea of Coplein's "Advanced C++ Styles and Idioms", 1992,
// page 93.  Note many details have been omitted for the sake of clarity.
//
// Written by Wayne Pollock, Tampa Florida USA, 2000.

class Telephone
{
public:
   Telephone ();
   virtual void ring ();
   virtual bool isOnHook ();
   virtual bool isTalking () = 0;  // A "pure virtual" function, so
                                   // class Telephone is now "abstract".
   virtual bool isDialing ();
   LineNumber get_extension ();
   virtual ~Telephone ();

protected:
   LineNumber extension;
};

//Note we can still define a Telephone::isTalking() function, and invoke it!
void Telephone::isTalking () { ... }

class POTSPhone : public Telephone  // POTS = Plain Old Telephone Service
{
public:
   void isTalking () { Telephone::isTalking(); }  // Must define this member.
   ~POTSPhone () { ... }
   ...      // The rest of this class is unchanged.
};

class ISDNPhone : public Telephone  // Integrated Services digital Network
{
   void isTalking () { Telephone::isTalking(); }  // Must define this member.
   ...      // The rest of this class is unchanged.
};

class OperatorPhone : public ISDNPhone   // Note: inherits from ISDNPhone.
{
   void isTalking () { Telephone::isTalking(); }  // Must define this member.
   void ring () { ... }
   ...      // The rest of this class is unchanged.
};

class PrincessPhone : public POTSPhone  // A kind of POTSPhone.
{
   void isTalking () { Telephone::isTalking(); }  // Must define this member.
   ...      // The rest of this class is unchanged.
};

void ring_phones ( Telephone* phone_list [] )
{
   for ( Telephone* p = phone_list; p; ++p )  // End of list marked with NULL
      p->ring();
}

int main ()
{
   Telephone* phone_array[10];
   int i = 0;
   phone_array[i++] = new POTSPhone( "5384" );
   phone_array[i++] = new ISDNPhone( "1050" );
   phone_array[i++] = new OperatorPhone( "0" );
   phone_array[i++] = new POTSPhone( "5385" );
   ...
   phone_array[i++] = NULL;
   ring_phones( phone_array );
   ...
   delete phone_array[0];  // Note correct destructor is called!
   ...
   return 0;
}