// CVirtual.cpp
// Demonstrate the importance of 'virtual' to achieve polymorphism

#include <iostream>

using namespace std;

class Shape {
 public:
	Shape()  { cout << "CTOR Shape" << endl; }
	~Shape() { cout << "DTOR Shape" << endl; }
	void displayNV()        { cout << "I am a Shape" << endl; }
	virtual void displayV() { cout << "I am a Shape" << endl; }
};

class Box : public Shape {
 public:
	Box()  { cout << "CTOR Box" << endl; }
	~Box() { cout << "DTOR Box" << endl; }
	void displayNV() { cout << "I am a Box" << endl; }
	void displayV()  { cout << "I am a Box" << endl; }
};

class Circle : public Shape {
  public:
	Circle()  { cout << "CTOR Circle" << endl; }
	~Circle() { cout << "DTOR Circle" << endl; }
	void displayNV() { cout << "I am a Circle" << endl; }
	void displayV()  { cout << "I am a Circle" << endl; }
};

int main(void)
{
	cout << endl << "CVirtual..." 
		 << endl << "Show the effect of 'virtual'"
		 << endl << endl;
	{
		cout << "CTORs are called" << endl;
		Shape shape;
		Box box;
		Circle circle;

		Shape *shapes[3] = { &shape, &box, &circle };

		cout << endl 
			 << "FOR: Note all calls result in 'Shape' - no polymorphism" 
			 << endl;
		for (int i = 0; i < 3; i++)
			shapes[i]->displayNV();

		cout << endl 
			 << "FOR: Note all calls now are polymorphic" 
			 << endl;;
		for (int i = 0; i < 3; i++)
			shapes[i]->displayV();

		cout << endl << "Calling DTORs..." << endl;
	}

	cout << endl;
	return 0;
}

/* ----- output -----

CVirtual...
Show the effect of 'virtual'

CTORs are called
CTOR Shape
CTOR Shape
CTOR Box
CTOR Shape
CTOR Circle

FOR: Note all calls result in 'Shape' - no polymorphism
I am a Shape
I am a Shape
I am a Shape

FOR: Note all calls now are polymorphic
I am a Shape
I am a Box
I am a Circle

Calling DTORs...
DTOR Circle
DTOR Shape
DTOR Box
DTOR Shape
DTOR Shape

----- end output ----- */
