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
---------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------