/* Author: Arun Somasundaram, CSE Dept, OSU. Simple program to understand different constructors, assignment operator, destructor, const member functions, inline functions and static variables. Answer the various questions listed in the program. The program has the Polygon and Rectangle classes & the main function. The Polygon/Rectangle classes listed below are not complete classes and they are used for demonstration purposes. For example, data such as (x, y) coords of the polygon vertices are missing. g++ -o constructorExec constructorExamples.cpp */ #include using namespace std; class Polygon{ protected: //Why protected? Will private work here for this program? int numVerts; // number of Vertices int *colorIndex; //index of color for each vertex public: static int numCount; //count of polygon objects. Why static? Polygon(); //default constructor Polygon(const Polygon &p); // what constructor is this? //Why wouldn't a default one be enough for the above constructor? Polygon(int numV, int *cIndex); Polygon& operator= (const Polygon &p); //assignment operator ~Polygon(); int getNumberOfVertices() {return numVerts;} // inline function. Why? void setNumberOfVertices(int nV); void printColorIndex() const; // Why is this declared a const func.? //It is a good habit to specify both your own copy constructor and the assignment operator instead of just specifying only either one of these. Remember that a copy constructor is different from the assignment operator even though both might seem to just copy values from one object to another. What is the difference between both? }; Polygon::Polygon(){ cout << "Polygon Default constructor is called." << endl; numVerts = 0; colorIndex = NULL; numCount++; } Polygon::Polygon(int numV, int *cIndex){ cout << "Polygon Constructor with 2 arguments is called." << endl; numVerts = numV; colorIndex = new int[numVerts]; for(int i = 0; i < numVerts; i++){ colorIndex[i] = cIndex[i]; } numCount++; } //Copy Constructor Polygon::Polygon(const Polygon &p){ //Why is the argument of the copy constructor a constant cout << "Polygon Copy Constructor is called." << endl; numVerts = p.numVerts; colorIndex = new int[numVerts]; for(int i = 0; i < numVerts; i++){ colorIndex[i] = p.colorIndex[i]; } numCount++; } //Assignment Operator Polygon & Polygon::operator= (const Polygon &p){ //Why is this assignment operator different from the copy constructor? cout << "Assignment operator is used." << endl; if (this != &p){ //don't assign object to itself //What is "this" in the above statement? if (colorIndex != NULL) delete [] colorIndex; numVerts = p.numVerts; colorIndex = new int[numVerts]; for(int i = 0; i < numVerts; i++){ colorIndex[i] = p.colorIndex[i]; } } else{ cout << "Warning: Assignment to itself." << endl; } } Polygon::~Polygon(){ cout << "Polygon Destructor is called." << endl; if (colorIndex != NULL) { delete [] colorIndex; colorIndex = NULL; } } inline void Polygon::setNumberOfVertices(int nV){ //Inline function. What is an inline function? numVerts = nV; } void Polygon::printColorIndex() const{ //Why is this a const function? cout << "Printing Color Index... " << endl; cout << " NumColors " << numVerts << endl; for(int i = 0; i < numVerts; i++){ cout << " " << i << ", " << colorIndex[i] << endl; } cout << endl; //numVerts = 7; //error? Why? } int Polygon::numCount = 0; //Static Variables have to declared outside the class interface when they need to be used outside of that class. /************ Simple Rectangle class derived from Polygon class ***/ class Rectangle : public Polygon{ private: int width, height; public: Rectangle(); Rectangle(int w, int h, int *cIndex); ~Rectangle(); }; Rectangle::Rectangle(){ cout << "Rectangle default constructor is called " << endl; numVerts = 4; width = 0; height = 0; } Rectangle::Rectangle(int w, int h, int *cIndex) : Polygon(4, cIndex){ cout << "Rectangle constructor with three arguments is called " << endl; width = w; height = h; } Rectangle::~Rectangle(){ cout << "Rectangle destructor is called" << endl; } /*************************************************************/ int main(){ int * colIndex; int numVerts = 4; colIndex = new int[numVerts]; for (int i = 0; i < numVerts; i++){ colIndex[i] = 100 + i; } cout << "P1 " << endl; Polygon p1; //Which constructor is called p1.printColorIndex(); cout << "P2 " << endl; Polygon p2(numVerts, colIndex); p2.printColorIndex(); cout << "P3 " << endl; Polygon p3(p2); //Which constructor is called p3.printColorIndex(); cout << "P4 " << endl; Polygon p4 = p2; //Assignment operator or constructor? p4.printColorIndex(); cout << "P5 " << endl; Polygon p5; p5.printColorIndex(); p5 = p2; //Assignment operator or constructor? p5.printColorIndex(); p5 = p5; //What happens due to this statement? cout << endl; cout << "P6 " << endl; Polygon &p6 = p5; //What happens here? p6.printColorIndex(); cout << "P7 " << endl; Polygon *p7 = new Polygon(p2); p7->printColorIndex(); cout << "Number of polygons " << Polygon::numCount << endl << endl; //Why only 6 polygons? Rectangle r1; //r1.printColorIndex(); // What happens if I unblock this statement? Why? cout << endl; Rectangle r2(25, 50, colIndex); //What happens here? //Note the order of constructor calls. r2.printColorIndex(); //Always remember to deallocate all dynamically allocated memory delete p7; delete [] colIndex; //deleting array. Note [] return 0; }