Possible Duplicate:
Can someone explain C++ Virtual Methods?
I have a question regarding to the C++ virtual functions.
Why and when do we use virtual functions? Can anyone give me a real time implementation or use of virtual functions?
Possible Duplicate:
Can someone explain C++ Virtual Methods?
I have a question regarding to the C++ virtual functions.
Why and when do we use virtual functions? Can anyone give me a real time implementation or use of virtual functions?
You use virtual functions when you want to override a certain behavior (read method) for your derived class rather than the one implemented for the base class and you want to do so at run-time through a pointer to the base class.
The classic example is when you have a base class called Shape
and concrete shapes (classes) that derive from it. Each concrete class overrides (implements a virtual method) called Draw()
.
The class hierarchy is as follows:
The following snippet shows the usage of the example; it creates an array of Shape
class pointers wherein each points to a distinct derived class object. At run-time, invoking the Draw()
method results in the calling of the method overridden by that derived class and the particular Shape
is drawn (or rendered).
Shape *basep[] = { &line_obj, &tri_obj, &rect_obj, &cir_obj}; for (i = 0; i < NO_PICTURES; i++) basep[i] -> Draw ();
The above program just uses the pointer to the base class to store addresses of the derived class objects. This provides a loose coupling because the program does not have to change drastically if a new concrete derived class of shape
is added anytime. The reason is that there are minimal code segments that actually use (depend) on the concrete Shape
type.
The above is a good example of the Open Closed Principle of the famous SOLID design principles.
Think of animals class, and derived from it are cat, dog and cow. Animal class has a
virtual void SaySomething() { cout << "Something"; }
function.
Animal *a; a = new Dog(); a->SaySomething();
Instead of printing "Something", dog should say "Bark", cat should say "Meow". In this example you see that a is a Dog, but there are some times that you have an animal pointer and don't know which animal it is. You don't want to know which animal it is, you just want the animal to say something. So you just call virtual function and cats will say "meow" and dogs will say "bark".
Of course, SaySomething function should have been pure virtual to avoid possible errors.
You use virtual functions when you need handle different objects in the same way. It`s called polymorphism. Let's imagine you have some base class - something like classical Shape:
class Shape { public: virtual void draw() = 0; virtual ~Shape() {} }; class Rectange: public Shape { public: void draw() { // draw rectangle here } }; class Circle: public Shape { public: void draw() { // draw circle here } };
Now you can have vector of different shapes:
vector<Shape*> shapes; shapes.push_back(new Rectangle()); shapes.push_back(new Circle());
And you can draw all shapes like this:
for(vector<Shape*>::iterator i = shapes.begin(); i != shapes.end(); i++) { (*i)->draw(); }
In this way you are drawing different shapes with one virtual method - draw(). Proper version of method is selected based on run time information about type of object behind pointer.
Notice When you use virtual functions you can declare them as pure virtual(like in class Shape, just place " = 0" after method proto). In this case you won't be able to create instance of object with pure virtual function and it will be called Abstract class.
Also notice "virtual" before destructor. In case when you are planning work with objects through pointers to their base classes you should declare destructor virtual, so when you call "delete" for base class pointer, all chain of destructors will be called and there won't be memory leaks.
You would use a virtual function to implement "polymorphism", in particular where you have an object, don't know what the actual underlying type is, but know what operation you want to perform on it, and the implementation of this (how it does it) differs dependent on what type you actually have.
Essentially what is commonly called the "Liskov Substitution Principle" named after Barbara Liskov who spoke about this around 1983.
Where you need to use dynamic runtime decisions where, at the point the code invoking the function is called, you do not know what types may pass through it, either now or in the future, this is a good model to use.
It isn't the only way though. There are all sorts of "callbacks" that can take a "blob" of data and you might have tables of callbacks dependent on a header block in the data that comes in, e.g. a message processor. For this there is no need to use a virtual function, in fact what you would probably use is sort-of how a v-table is implemented only with one entry (e.g. a class with just one virtual function).