ref – https://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c?rq=1
Simple Over-riding
Without “virtual” you get “early binding”. Which implementation of the method is used gets
decided at compile time based on the type of the pointer that you call through.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include <iostream> using namespace std; // Without "virtual" you get "early binding". // Which implementation of the method is used gets // decided at compile time based on // "the type of the pointer that you call through". class Shape { public: Shape() { cout << "\nConstructing Shape" << endl; } // NO VIRTUAL. just a base function to be over-ridden void draw() { cout << "\n SHAPE: Draw function" << endl; } }; class Circle : public Shape { private: float mRadius; public: Circle(float newRadius) { cout << "\nConstructing Circle" << endl; this->mRadius = newRadius; } void draw() { cout << "\n Circle: draw function" << endl; } }; // due to the parameter of func being Shape *, // without virtual, we get early binding. At compile time, // it is decided that Shape will be used. And thus, // any objects that derives from Shape passed int, will literally // use Shape as the implementation. All draw() are called upon the // Shape implementation. void func(Shape * s) { s->draw(); } int main(int argc, const char * argv[]) { Circle * myCircle = new Circle(6.8); Shape * myShape = new Shape(); func(myShape); func(myCircle); delete myCircle; delete myShape; return 0; } |
OUTPUT:
Constructing Shape
Constructing Circle
Constructing Shape
SHAPE: Draw function
SHAPE: Draw function
Using Virtual
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include <iostream> using namespace std; // With "virtual" you get "late binding". // Which implementation of the method is used gets decided // at run time based on the type of the pointed-to object - // what it was originally constructed as. This is not necessarily // what you'd think based on the type of the pointer that points to that object. class Shape { public: Shape() { cout << "\nConstructing Shape" << endl; } // virtual functions resolved at runtime virtual void draw() { cout << "\n SHAPE: Draw function" << endl; } }; class Circle : public Shape { private: float mRadius; public: Circle(float newRadius) { cout << "\nConstructing Circle" << endl; this->mRadius = newRadius; } void draw() { cout << "\n Circle: draw function" << endl; } }; void func(Shape * s) { s->draw(); } int main(int argc, const char * argv[]) { Circle * myCircle = new Circle(6.8); Shape * myShape = new Shape(); func(myShape); func(myCircle); delete myCircle; delete myShape; return 0; } |
OUTPUT:
Constructing Shape
Constructing Circle
Constructing Shape
SHAPE: Draw function
Circle: draw function