Archived

This topic is now archived and is closed to further replies.

Nat

Virtual Funtions

Recommended Posts

Nat    122
Ok.. I know how to use Virtual Funtions and all ..but can anobody List why it is used and what are its benifits. thanks

Share this post


Link to post
Share on other sites
Merge2    122
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

Share this post


Link to post
Share on other sites
Nat    122
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?

Share this post


Link to post
Share on other sites
Renus    122
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

Share this post


Link to post
Share on other sites
Grugnorr    122
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[i]->Release();

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()....

I´m leaving... if you want something, post it here...BYE







What the hells!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
by the way, if you do not declare base class functions as virtual, you lose polymorphic effect.

Share this post


Link to post
Share on other sites
Nat    122
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!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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.


Share this post


Link to post
Share on other sites
Grugnorr    122
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!

Share this post


Link to post
Share on other sites
Grugnorr    122
Nat the MAIN difference between using or not virtual functions in your example is storing them, as I´m saying. Try to store them in a simple array, loop it drawing all the array. How would you do that?

.-If you want to use the derived Draw()(NOT using virtual functions) you have to call that method form the derived class_(or a pointer to it ).

.-Think and try what i have said.

What the hells!

Share this post


Link to post
Share on other sites