Here's a shorter explanation. It is a summary of what's in Ivor Horton's Beginning Visual C++ 5.0 book, chapter 10. Suppose you have the following class that contains info on a box's dimensions and methods for outputting the volume of the box to the screen:
Code:
class CBox
{
public:
void ShowVolume(void)
{
cout << endl << "CBox usable volume is " << Volume();
}
double Volume(void)
{
return m_Length * m_Height * m_Breadth;
}
CBox( double lv=1.0, double bv=1.0, double hv=1.0) : m_Length(lv),
m_Breadth(bv),
m_Height(hv)
{
}
protected:
double m_Length;
double m_Breadth;
double m_Height;
}
Now you create a derived class to contain glassware where the volume will be 15% less than the usual volume given by a box with the same dimensions:
Code:
class CGlassBox: public CBox
{
public:
double Volume(void)
{
return 0.85 * m_Length * m_Breadth * m_Height;
}
}
If you create and output the volumes of two different boxes using the following program fragment:
Code:
CBox myBox(2.0,3.0,4.0);
CGlassBox myGlassBox(2.0,3.0,4.0);
myBox.ShowVolume();
myGlassBox.ShowVolume();
You get the following results:
CBox usable volume is 24
CBox usable volume is 24
The first result is correct but the second should be 15% less. This is because the call to the Volume() function is being set once by the compiler for the version defined in the base class. This is called static linkage and the call gets fixed to only that version when the code gets compiled. What is needed is to have the actual version of the Volume() function that is called by ShowVolume() function to be determined based on the kind of object being processed in what is know as dynamic linkage. This is why you need virtual functions. Simply adding the word virtual prior to the Volume() function definition in the base class will solve this problem although it is good practice to also put it in the derived class as well. You would then get the proper results:
CBox usable volume is 24
CBox usable volume is 20.4