//*************************************************************************
#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;
}