//*************************************************************************

#include <iostream>     //inclusion of support for doing input & output

#include <string>       //inclusion of support of the string class

#include <vector>       //inclusion of support of the vector class

using namespace std;    //declare access to standard stuff like cin, cout

 

 

 

//*************************************************************************

//    Base class declaration

//*************************************************************************

class baseClass

{     public:

            baseClass(string name="ANONYMOUS");

 

            virtual ~baseClass();   //What is the effect of virtual??

            //~baseClass();               //What happens if no virtual??

 

            virtual void output();  //What is the effect of virtual??

            //void output();        //What happens if no virtual??

 

            static int count;

 

      private:

            string baseName;

};

 

 

//*************************************************************************

//    Base class implementation

//*************************************************************************

 

 

int baseClass::count = 0;

 

baseClass::baseClass(string name)

{

      baseName = name;

      ++count;

      cout  << endl

                  << baseName

                  << ", a new baseClass object is CONSTRUCTED."

                  << endl << "Now "

                  << count << " baseClass objects in total."

                  << endl << endl;

}

 

baseClass::~baseClass()

{

      --count;

      cout  << endl

                  << baseName

                  << ", a baseClass object is DESTRUCTED."

                  << endl << "Now "

                  << count << " baseClass class objects in total."

                  << endl << endl;

}

 

void baseClass::output()

{

      cout << endl << "Hello! I am " << baseName << ", a baseClass object " << endl;

}

 

 

 

 

 

 

 

//*************************************************************************

//    Child class A declaration

//*************************************************************************

 

class childClassA:public baseClass

{

      public:

      childClassA(string name);

      ~childClassA();

      void output();

      static int count;

 

      private:

      string childName;

};

 

 

 

//*************************************************************************

//    Child class A implementation

//*************************************************************************

int childClassA::count = 0;

 

childClassA::childClassA(string name)

{

      childName = name;

      ++count;

      cout  << endl

                  << childName

                  << ", a new childClassA object is CONSTRUCTED."

                  << endl << "Now "

                  << count << " childClassA objects in total."

                  << endl << endl;

}

 

childClassA::~childClassA()

{

      --count;

      cout  << endl

                  << childName

                  << ", a childClassA object is DESTRUCTED."

                  << endl << "Now "

                  << count << " childClassA objects in total."

                  << endl << endl;

}

 

void childClassA::output()

{

      cout << endl << "Hello! I am " << childName << ", a childClassA object. " << endl

            << "I am also a baseClass object: ";

      baseClass::output();

}

 

 

 

 

//*************************************************************************

//    Child class B declaration

//*************************************************************************

 

class childClassB:public baseClass

{

      public:

      childClassB(string name);

      ~childClassB();

      void output();

      static int count;

 

      private:

      string childName;

};

 

 

 

//*************************************************************************

//    Child class B implementation

//*************************************************************************

int childClassB::count = 0;

 

childClassB::childClassB(string name)

{

      childName = name;

      ++count;

      cout  << endl

                  << childName

                  << ", a new childClassB object is CONSTRUCTED."

                  << endl << "Now "

                  << count << " childClassB objects in total."

                  << endl << endl;

}

 

childClassB::~childClassB()

{

      --count;

      cout  << endl

                  << childName

                  << ", a chilClassB object is DESTRUCTED."

                  << endl << "Now "

                  << count << " childClassB objects in total."

                  << endl << endl;

}

 

void childClassB::output()

{

      cout << endl << "Hello! I am " << childName << ", a childClassB object. " << endl

           << "I am also a baseClass object: ";

      baseClass::output();

}

 

 

 

 

//*************************************************************************

//    A simple waiting function

//*************************************************************************

void wait()

{     char ch;

      cout << endl << "******************************************************" << endl;

      cout << "Press c to continue" << endl;

      cin >> ch;

}

 

 

 

 

//*************************************************************************

//    The test function

//*************************************************************************

void test()

{    

 

      //*************************************************************************

     //Observe the implicit calls to constructors of the base and the child classes

      //*************************************************************************

      baseClass jacob("JACOB");

      wait();

      childClassA joseph("JOSEPH");

      wait();

      childClassB benjamin("BENJAMIN");

      wait();

 

 

      //*************************************************************************

     //Observe (i) the implicit calls to constructors of the base and the child classes

      //        (ii) basePtrVector as a vector of polymorphic pointers after type cast

      //*************************************************************************

vector<baseClass *> basePtrVector;

 

basePtrVector.push_back( (baseClass *) new childClassB("TIMOTHY") );

wait();

 

basePtrVector.push_back( (baseClass *) new childClassA("PAUL")          );

wait();

 

basePtrVector.push_back( (baseClass *) new childClassB("TITUS")         );

wait();

 

 

      //*************************************************************************

      //Observe and think about the effects of polymorphism and dynamic method binding here

      //*************************************************************************

      for ( vector<baseClass *>::iterator i=basePtrVector.begin();

                  i < basePtrVector.end();

                  ++i

          )

      {     (*i)->output();

      }

 

      wait();

 

 

 

      //*************************************************************************

//Observe the implicit calls to the destructors of the base and the child classes

      //*************************************************************************

      delete basePtrVector[0];

      wait();

 

 

      //*************************************************************************

      //Think about the issue of memory leak here. Is there a memory leak at this pont.

      //*************************************************************************

      basePtrVector.clear();

 

 

      cout <<  "... time spent in basePtrVector.clear() ..."  <<  endl;

      wait();

 

}    

 

 

//*************************************************************************

//     The main function just call the test function

//*************************************************************************

int  main()

{    

      test();

      cout << "This is the end of the call to the test function." << endl;

      //*************************************************************************

     //Observe the implicit calls to the destructors of the base and the child classes

      //Also think about the issue of memory leak here again.

      //*************************************************************************

 

      wait();

 

      cout << "This is the end of the main function." << endl;

      return 0;

}