Advertisement

Virtual Funtions

Started by March 16, 2001 03:14 AM
9 comments, last by Nat 23 years, 10 months ago
Ok.. I know how to use Virtual Funtions and all ..but can anobody List why it is used and what are its benifits. thanks
~~~º¥º -
Take game programming for example. In the old days of game programming if you wanted to support video hardware acceleration, you had to write your program so it could use ONE specific graphics card, and if you wanted to support 4 video cards, you had to add support for 4 video cards.

Nowadays, you can use DirectX or OpenGL and use a general function, let''s use the fictional DrawLine() function. In the old days, you would have had to write different functions for different video cards, for example:

DrawLineVoodoo()
DrawLineNvidia()
DrawLineATI()
etc...

Let''s say that DirectX has a DrawLine() function. Well, DX''s DrawLine() function would really be a virtual function. And what DirectX''s DrawLine() function would really do, is run DrawLineVoodoo() or whatever video card you have. I think this is correct anyway.

I think the basic advantage is that you can have one interface, and many implementations. In the case of video cards, you can write your program with one interface that calls DrawLine(), and there are many interfaces (DrawLineVoodoo(), DrawLineNvidia(), etc.) and you as the programmer don''t have to worry about what kind of video card the user has, or if they even have a video card for that matter. You just call DrawLine() and DirectX or OpenGL or whatever will take care of the hardware acceleration or lack thereof.

If this explaination isn''t correct, please flame me to no end
Advertisement
Ok! but what if we had a base class and we did not make the functions virtual ..still we can override these funtions in the derived classes. Like you said .. DrawLine is present in the base class say, but it is not declared virtual .. still we can override this in the derived classes and still acheive the same funtionality .. so what does making the funtion virtual acheive?
~~~º¥º -
The benefit of virtual functions, e.g. for game programming, are best explained by the state machine which most games (should) have.

Assume you have a base state class which is "pure virtual" and has only virtual functions like "Render()", "Animate()", "Enable()", "Disable()". Now you can override these functions for your concrete states, e.g. The world renderer, the object renderer, the skybox, the menu, etc. Your main engine class will now just cycle through all those state classes and call the "Render()" funtion, it has no idea what it renders, it just knows that states have a Render() method. You can easily extend this pattern by adding a new class, e.g. CExplosions. Since your main engine class does not need to know the details about it, you just append another state (not a CExplosion) and it will render it as all other states. The Good Thing is, in contrast to just overriding a base calss function), that you dont have to deal with CExplosion in this example - all the engine class receives is a CState class. So you work with abstract classes while all non-polymorph ways will force you to let the owner know and deal with your concrete classes.

Another example: you have some helicopters, some planes and some pedestrians in your game. Hide the physical behaviour in a concrete class while all common things can be put in a abstract base class. Again your engine just cycles through visible objects and renders/steers them without knowing what''s behind.

Essentials for those virtual things are:
- declare your destructors all virtual
- know that you always can cast a derived class to a base class (this actually hides the information and allows to share common funciotnality)
- AND know that you also can safely convert a base class pointer into the concrete derived class (enable RTTI-flag in settings for this). The latter is not necessarily to be used; you can also enjoy the polymorphism without this..
- DESIGN before implementing your classes. After some time (years..) you will easily identify the right cases where to use it and where not, it''s worth the initial "overhead".

Just email me on further questions,
Renus

- thomas
- thomas
To take it simple here it is a nice example:

You want to draw different shapes on the screen. I´ll do:
Make an(abstract) base class called CShape. This has the common things between all the shapes AND the interface common to all of them(The methods that they have in common:Draw(),Move(x,y).... .
Each of the concrete shapes:CQuad for example implement their own virtual method,like Draw()...
I now want tho store all the shapes on the screen, I can do: Make an array of POINTERS TO THE BASE CLASS,CShape.Fill it with the pointres to each CONCRETE class, and operate ALL the shapes using the CShape interface.Example:

CShape* ArrShapes[2];//To keep it simple

CTriangle* pTri=new CTriangle;
CBox* pBox=new CBox;

ArrShapes[0]=pTri;
ArrShapes[1]=pBox;

for(int i=0;i ArrShapes->Draw();

for(int i=0;i ArrShapes->Release();<br><br>I must go….You could make a DisplayList class.It stores pointers to the base class all the DisplayObjects are derived from.Implement a Loop() method that goes trough the list and draw all the objects…Release()….<br><br> I´m leaving… if you want something, post it here…BYE<br><br><br><br><br><br> </i> <br><br>What the hells!
What the hells!
Virtual functions allow you to exploit polymorphism. This is, in my humble opinion, the most powerful element of the object oriented programming (Liskov''s substitution principle they call it). Basically, using virtual functions and polymorphism, you can create a framework of the program where you can operate on objects based on their base class interface (also called interface classes) and define the behavior separately on derived classes by over-riding the virtual (or pure virtual) functions. If done correctly, you can maintain orthogonality between the functional aspect of the program and the archtectural aspect (frame work) of the program. It really is a useful concept.
Advertisement
by the way, if you do not declare base class functions as virtual, you lose polymorphic effect.
Ok! the benifits of Virtual is somewhat clear(Virtual ). But AP you had said we would loose polymorphic effect if we did not have the base class funtions as virtual. But Say we have CCirle, CSquare, CTriangle all derived from CShape and we did not declare the draw as virtual in the base class, we have draw() in the base class. Now we have overidden the draw() in CCircle, Csquare and CTriangle. But still we can call draw() on each of the derived objects and they give us the same funtionality, is it not!
~~~º¥º -
You are absolutely correct. But consider what happens when you try to implemet an operator on your shape objects. Most obvious way would be to declare it as follows (imagine X is your operator class);

void X::operator()(const CShape& s)
{
...
s.Draw();
...
}
Which will be used as follows;
X x;
CSquare sq;
CTriangle tr;
x(sq);
x(tr);

However, the call to draw will only call base class Draw and not your intended derived Draw. In order to invoke your derived Draw call, the operator will have to be modified as follows;

int X::operator(const CSquare& sq) { ... }
int X::operator(const CTriangle& tr) { ... }

Or worse yet, use RTTI ... :p

When you add new shape, say CBlob, you will have to modify your X definition by adding a new operator class for CBlob (and so on).

By declaring your base class Draw as virtual, you can pass in your object in terms of your base class and get back the functionality you defined in your derived class. This is called polymorphism.


If you don´t declare Draw() as virtual, you won´t be able to use all the different concrete shapes(CBox,CCircle....) as if they were the same. Think about this(again):

.-How will you store and draw all the objects on the screen or in the level? If there are,say 10 types of DIFFERENT objects?. Store them in a different list and loop through each one?. Looping takes time... And if you want to add another DIFFERENT object? Another list and change the DrawingAllTheScreen
code?.




What the hells!
What the hells!

This topic is closed to new replies.

Advertisement