Reading

---------------------------------------------------------------------------------------------------------------------------------------------------------------
Polymorphism
---------------------------------------------------------------------------------------------------------------------------------------------------------------


File: classes.h 

#pragma once
#include "cmpslib19.h"

class lifeform
{
public:
lifeform();
~lifeform();
string ToString();
};

class amoeba : public lifeform
{
public:
amoeba();
~amoeba();
string ToString();
};

class armadillo : public lifeform
{
public:
armadillo();
~armadillo();
string ToString();
};






File: main1.cpp

#include "cmpslib19.h"


/* classes.h and classes.cpp  are the non virtual  
versions of the lifeform,amoeba and armadillo classes */
#include "classes.h"




/* 
this is not using polymorphism
we will simply create some instances / objects
of the 3 classes
a lifeform object can only be a life form,
an amoeba object  can only be an amoeba
an armadilo can only be an armadillo

everything will work as you would expect
*/

int main()
{


  // create a scope so that the life time of the objects created will end
	{
		cout<<"\n\nCreate an instance of the lifeform class\n";
		lifeform a;
		cout <<"a.ToString returns \n" <<  a.ToString()<< endl;
		cout<<"\n\nDestroy instance of the lifeform class\n";
	}
  // at the end of the scope anything created with in will be destroyed.. 


	{
		cout<<"\n\nCreate an instance of the amoeba class\n";
		amoeba  b;
		cout <<"b.ToString returns \n" <<  b.ToString()<< endl;
		cout<<"\n\nDestroy instance of the amoeba class\n";
	}


	{
		cout<<"\n\nCreate an instance of the armadillo class\n";
		armadillo c;
		cout <<"c.ToString returns \n" <<  c.ToString()<< endl;
		cout<<"\n\nDestroy instance of the armadillo class\n";
	}


	return 0;
}

File: output1.txt



Create an instance of the lifeform class
In the lifeform constructor
a.ToString returns 
ima lifeform


Destroy instance of the lifeform class
In the lifeform destructor


Create an instance of the amoeba class
In the lifeform constructor
In the amoeba constructor
b.ToString returns 
            ,,,,,,,,
           ,|||````||||
     ,,,,|||||       ||,
  ,||||```````       `||
,|||`                 |||,
||`     ....,          `|||
||     ::::::::          |||,
||     :::::::'     ||    ``|||,
||,     :::::'               `|||
`||,                           |||
 `|||,       ||          ||    ,||
   `||                        |||`
    ||                   ,,,||||
    ||              ,||||||```
   ,||         ,,|||||`
  ,||`   ||   |||`
 |||`         ||
,||           ||
||`           ||
|||,         |||
 `|||,,    ,|||
   ``||||||||`


Destroy instance of the amoeba class
In the amoeba destructor
In the lifeform destructor


Create an instance of the armadillo class
In the lifeform constructor
In the armadillo constructor
c.ToString returns 

             ,.-----__    
          ,:::://///,:::-. 
         /:''/////// ``:::`;/|/
        /'   ||||||     :://'`\ 
      .' ,   ||||||     `/(  e \ 
-===~__-'\__X_`````\_____/~`-._ `.
           ~~        ~~       `~-'         


Destroy instance of the armadillo class
In the armadillo destructor
In the lifeform destructor

ok here we have created an instance of all 3 classes and when we call the ToString fucntions on all 3 of them it works like we would expect --------------------------------------------------------------------------------------------------------------------------------------------------------------- File: main2.cpp

#include "cmpslib19.h"


/* classes.h and classes.cpp  are the non virtual  
versions of the lifeform,amoeba and armadillo classes */
#include "classes.h"

/* 
   here we will use  polymorphism INCORRECTLY

   we will create some instances / objects
   of the 3 classes but we will use new and access them via a pointer to the 
   base class lifeform 

   a pointer to a lifeform can be assigned the address of a object can only be a lifeform,amoeba or armadilo

   
   calling the ToString method will always result in resolving to the ToString method of the 
   base class, that is not the result we want 

	 furthermore and very important the destructor of the proper class is not called either
*/





int main()
{


	{
		cout<<"\n\nCreate an instance of the lifeform class\n";
		lifeform* a = new lifeform;
		cout <<"a->ToString returns \n" <<  a->ToString()<< endl;
		cout<<"\n\nDestroy instance of the lifeform class\n";
		delete a;
	}



	{
		cout<<"\n\nCreate an instance of the amoeba lifeform class\n";
		lifeform* b = new amoeba;
		cout <<"b->ToString returns \n" <<  b->ToString()<< endl;
		cout<<"\n\nDestroy instance of the amoeba class\n";
		delete b;
	}




	{
		cout<<"\n\nCreate an instance of the armadillo class\n";
		lifeform* c= new armadillo;
		cout <<"c->ToString returns \n" <<  c->ToString()<< endl;
		cout<<"\n\nDestroy instance of the armadillo class\n";
		delete c;
	}


	return 0;
}

File: output2.txt



Create an instance of the lifeform class
In the lifeform constructor
a->ToString returns 
ima lifeform


Destroy instance of the lifeform class
In the lifeform destructor


Create an instance of the amoeba lifeform class
In the lifeform constructor
In the amoeba constructor
b->ToString returns 
ima lifeform


Destroy instance of the amoeba class
In the lifeform destructor


Create an instance of the armadillo class
In the lifeform constructor
In the armadillo constructor
c->ToString returns 
ima lifeform


Destroy instance of the armadillo class
In the lifeform destructor

in this one we are using a pointer3 to the base class and seting them to instances of the 3 different classes things to NOTE the correct constructor is called the WRONG descructor and and ToString functions get called .. since we are using pointers to the base class (lifeform) it calls the desctructor and ToString of the lifeform class. Polymorphism will fix that --------------------------------------------------------------------------------------------------------------------------------------------------------------- here are the classes gain but we use the virtual keyword we will make the ToString function virtual so it will call the correct version and we also make the destructor virtual as well if you make even one single function virtual you should always, always, always make the destructor virtual File: classes2.h

#pragma once
#include "cmpslib19.h"

class lifeform
{
public:
lifeform();
~lifeform();
virtual string ToString();
};

class amoeba : public lifeform
{
public:
amoeba();
~amoeba();
string ToString();
};

class armadillo : public lifeform
{
public:
armadillo();
~armadillo();
string ToString();
};






File: main3.cpp

#include "cmpslib19.h"


/* classes.h and classes.cpp  are the virtual  
versions of the lifeform,amoeba and armadillo classes */

#include "classes2.h"


/* 
this is not using polymorphism
we will simply create some instances / objects
of the 3 classes
a lifeform object can only be a life form,
an amoeba object  can only be an amoeba
an armadilo can only be an armadillo

everything will work as you would expect
even though we have declared our ToString and descructor to be virtual
it does not make a difference, we havent lost any functionality by 
creating virtual functions so there is not a downside

*/



int main()
{


	{
		cout<<"\n\nCreate an instance of the lifeform class\n";
		lifeform a;
		cout <<"a.ToString returns \n" <<  a.ToString()<< endl;
		cout<<"\n\nDestroy instance of the lifeform class\n";
	}



	{
		cout<<"\n\nCreate an instance of the amoeba lifeform class\n";
		amoeba  b;
		cout <<"b.ToString returns \n" <<  b.ToString()<< endl;
		cout<<"\n\nDestroy instance of the amoeba class\n";
	}




	{
		cout<<"\n\nCreate an instance of the armadillo class\n";
		armadillo c;
		cout <<"c.ToString returns \n" <<  c.ToString()<< endl;
		cout<<"\n\nDestroy instance of the armadillo class\n";
	}


	return 0;
}

File: output3.txt



Create an instance of the lifeform class
In the lifeform constructor
a.ToString returns 
ima lifeform


Destroy instance of the lifeform class
In the lifeform destructor


Create an instance of the amoeba lifeform class
In the lifeform constructor
In the amoeba constructor
b.ToString returns 
            ,,,,,,,,
           ,|||````||||
     ,,,,|||||       ||,
  ,||||```````       `||
,|||`                 |||,
||`     ....,          `|||
||     ::::::::          |||,
||     :::::::'     ||    ``|||,
||,     :::::'               `|||
`||,                           |||
 `|||,       ||          ||    ,||
   `||                        |||`
    ||                   ,,,||||
    ||              ,||||||```
   ,||         ,,|||||`
  ,||`   ||   |||`
 |||`         ||
,||           ||
||`           ||
|||,         |||
 `|||,,    ,|||
   ``||||||||`


Destroy instance of the amoeba class
In the amoeba destructor
In the lifeform destructor


Create an instance of the armadillo class
In the lifeform constructor
In the armadillo constructor
c.ToString returns 

             ,.-----__    
          ,:::://///,:::-. 
         /:''/////// ``:::`;/|/
        /'   ||||||     :://'`\ 
      .' ,   ||||||     `/(  e \ 
-===~__-'\__X_`````\_____/~`-._ `.
           ~~        ~~       `~-'         


Destroy instance of the armadillo class
In the armadillo destructor
In the lifeform destructor

--------------------------------------------------------------------------------------------------------------------------------------------------------------- File: main4.cpp

#include "cmpslib19.h"

/* 
classes2.h and classes2.cpp  are set up with virtual function
versions of the lifeform,amoeba and armadillo classes */
#include "classes2.h"


/* 
   here we will use  polymorphism CORRECTLY

   we will create some instances / objects
   of the 3 classes but we will use new and access them via a pointer to the 
   base class lifeform 

   a pointer to a lifeform can be assigned the address of a object can only be a lifeform,amoeba or armadilo

   everything will work as you would expect
   because we have virtual ToString method and destructor
*/



int main()
{
	{
		cout<<"\n\nCreate an instance of the lifeform class\n";
		lifeform* a = new lifeform;
		cout <<"a->ToString returns \n" <<  a->ToString() << endl;
		cout<<"\n\nDestroy instance of the lifeform class\n";
		delete a;
	}

	{
		cout<<"\n\nCreate an instance of the amoeba lifeform class\n";
		lifeform* b = new amoeba;
		cout <<"b->ToString returns \n" <<  b->ToString() << endl;
		cout<<"\n\nDestroy instance of the amoeba class\n";
		delete b;
	}

	{
		cout<<"\n\nCreate an instance of the armadillo class\n";
		lifeform* c= new armadillo;
		cout <<"c->ToString returns \n" <<  c->ToString() << endl;
		cout<<"\n\nDestroy instance of the armadillo class\n";
		delete c;
	}


	return 0;
}



File: output4.txt



Create an instance of the lifeform class
In the lifeform constructor
a->ToString returns 
ima lifeform


Destroy instance of the lifeform class
In the lifeform destructor


Create an instance of the amoeba lifeform class
In the lifeform constructor
In the amoeba constructor
b->ToString returns 
            ,,,,,,,,
           ,|||````||||
     ,,,,|||||       ||,
  ,||||```````       `||
,|||`                 |||,
||`     ....,          `|||
||     ::::::::          |||,
||     :::::::'     ||    ``|||,
||,     :::::'               `|||
`||,                           |||
 `|||,       ||          ||    ,||
   `||                        |||`
    ||                   ,,,||||
    ||              ,||||||```
   ,||         ,,|||||`
  ,||`   ||   |||`
 |||`         ||
,||           ||
||`           ||
|||,         |||
 `|||,,    ,|||
   ``||||||||`


Destroy instance of the amoeba class
In the lifeform destructor


Create an instance of the armadillo class
In the lifeform constructor
In the armadillo constructor
c->ToString returns 

             ,.-----__    
          ,:::://///,:::-. 
         /:''/////// ``:::`;/|/
        /'   ||||||     :://'`\ 
      .' ,   ||||||     `/(  e \ 
-===~__-'\__X_`````\_____/~`-._ `.
           ~~        ~~       `~-'         


Destroy instance of the armadillo class
In the lifeform destructor

--------------------------------------------------------------------------------------------------------------------------------------------------------------- File: main5.cpp

#include "cmpslib19.h"


/* classes.h and classes.cpp  are the non virtual  
versions of the lifeform,amoeba and armadillo classes */
#include "classes3.h"

/* 

   here we cast our pointers to the correct type before calling functions
   to get the desired result

   this is what needs to be done

   making our descructor and ToString function virtual would solve this 

*/





int main()
{


	{
		cout<<"\n\nCreate an instance of the lifeform class\n";
		lifeform* a = new lifeform;
		cout <<"a->ToString returns \n" <<  a->ToString()<< endl;
		cout<<"\n\nDestroy instance of the lifeform class\n";
		delete a;
	}



	{
		cout<<"\n\nCreate an instance of the amoeba lifeform class\n";
		lifeform* b = new amoeba;
		cout <<"b->ToString returns \n" << ((amoeba*) b)->ToString()<< endl;
		cout<<"\n\nDestroy instance of the amoeba class\n";
		delete (amoeba*) b;
	}




	{
		cout<<"\n\nCreate an instance of the armadillo class\n";
		lifeform* c= new armadillo;
		cout <<"c->ToString returns \n" <<  ((armadillo*)c)->ToString()<< endl;
		cout<<"\n\nDestroy instance of the armadillo class\n";
		delete (armadillo*)c;
	}


	return 0;
}

File: output5.txt


--------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------