Jump to content
  • Advertisement

Archived

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

Ghostface

Virtual functions? Inheritance? Why use them???

This topic is 6259 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Compared to most of the people here, I am new to programming. The only language that I have any experience with is C++, which I have been learning for the past 9-10 months. But, something perplexes me: why would anyone want to use virtual functions? They seem kind of pointless to me. Why not just override the base class''s function? From all of the examples I''ve seen, it seems that in order to use a virtual function, you must have an instance of a base class that points to an instance of a derived class, but must decide which function to use at runtime. Or something like that. It''s all gibberish to me. So...someone help me out please.

Share this post


Link to post
Share on other sites
Advertisement
Well, you''re sort of on the right track here. If a class''s function is virtual, it can be overridden in a child class. This is very, very useful. Here''s a stupid little example...suppose you have a generic CEnemy class, with a virtual function attack(). Then, suppose you have two child classes, CTroll and COgre. Each of these also has an attack(). Now, the magic of virtual functions:
  
CEnemy* pEnemy = new CTroll(...);
pEnemy->attack(); // CTroll''s attack() function gets called
pEnemy = new COgre(...);
pEnemy->attack(); // COgre''s attack() function gets called

I hope you can see just how useful this can be. Another example would be if you are iterating through a list of enemies, and each enemy is of a different type. All you have to do is call each enemy''s attack() function, and you know that the correct one will be called.

~~~~~~~~~~
Martee

Share this post


Link to post
Share on other sites
A virtual function basically forces derived objects to also perform the function according to what the base class has for that virtual function prior to performing the derived class''s overriden function.

The most common example of this is a destructor. It is wise to make destructors virtual due to the fact that you might need to delete allocated memory in the base class. For instance:


class Base
{
public:
Base() { myItem = new ITEM; } // default constructor
virtual ~Base() { delete myItem; } // virtual destructor
ITEM *myItem;
}

class Derived : public Base
{
public:
Derived(); // default constructor
virtual ~Derived(); // virtual destructor
}


In the previous example, myItem was allocated as memory that will require specific deletion. If the destructor were not virtual, then any constructed instances of Derive would not "be aware" that the memory needed to be deleted. Due to the fact that the destructor is virtual, the destructor for Base will be called, and the memory properly released, before the destructor for Derive will be completed. This is why destructors are always declared as virtual.

Other examples of wanting to use this functionality would be anything you wish to repeat across all derived classes. For instance, if you always wanted to draw something on every derived view, you could make the OnDraw virtual to force the same thing to be drawn first for all views.

There are several gotchas regarding this involving calling member functions from within virtual functions and vice versa, but I think this is enough to digest for now *smile*

-fel

Share this post


Link to post
Share on other sites
I forgot to note that base class constructors are implicitly virtual due to the fact that the base class must be constructed in conjunction with (and previous to, for that matter) any derived classes, though constructors are not labelled as such... in case there''s any confusion as to how the Base constructor got called in the first place.

-fel

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Your game might have a lot of objects that need to be updated every tick. They might be of many different types but fundamentally they need to get updated every tick. So you want to store them all in a list or a vector and update them all by iterating through the list right? You can''t do that unless you use pointers to derived classes. So what you do is you make a base class Updatable and give it a virtual method Update(). Then derive all of the things you want to be able to update from this class and implement the method. Now you can loop through. Oh and you can''t override a non virtual function, the word virtual means overridable. It might seem like you can but you aren''t doing what you think you are.

Another common use is for implementing what is known as the "strategy pattern". Let''s say you have a monster type and you need to make AI for it. Every now and then it appraises the situation and decides what to do. You could have a case statement, and have code for each situation. That is probably the best solution if you only need simple AI. However if you want things to be more complex or flexible it is time to break out inheritance. Make a Reaction class with a HandleSituation() method. Have Reaction* variables for all the different situations and put subclasses in them. Now in the case statement instead of putting the code directly call the HandleSituation method of the appropriate Reacton variable. There are some nice benefits to doing this. For one you can change behavior at runtime. You might have a spell that makes monsters laugh in response to certain situations, now it is easy, just swap in a subclass that does just that. You can also use the same set of Reaction classes to do all the AI for all your monsters, it makes things easier.

There are more uses of inheritance too but they mostly revolve the basic concept of changing behavior while retaining the same interface.

Share this post


Link to post
Share on other sites
The main contribution is interface reuse, which means that you build on a foundation of ABSTRACT base classes. Without virtual functions and the accompanying vtbls you couldn''t do this.

This is what COM is all about.

Share this post


Link to post
Share on other sites
I would like to thank everyone for their attempts to help me to understand the use of virtual functions, but I''m afraid that I still don''t understand. Could someone please give me a practical example of something that you would NOT want to do/cannot do without virtual functions?

They still seem pointless to me. But then again, I''m a novice programmer...

Share this post


Link to post
Share on other sites
I think you should buy a good C++ book...

And don´t tell me you can´t afford it...Get a job of some sort !

Share this post


Link to post
Share on other sites
I happen to have two C++ books (Teach Yourself C++ in 21 Days and Practical C++). And neither one of them does a very good of explaining the practicality/uses of virtual functions.

And I''m only 15, which is not quite old enough to get a job at most places

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!