What means virtual

Hi,
can someone explain in easy words (for Dummies) what is the difference between a virtual function and a normal function?

vitrual void myfunc();
or
void myfunc();
Ingo FoersterProgrammerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Russ SuterCommented:
This is only important if you're using inheritance.

A virtual function is one that performs some kind of function in a base class but it can be overridden by a different version of the same function in a derived class.
class parent {
public:
  virtual void handle_event(int something) {
    // boring default code
  }
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1);
}

Open in new window

0
evilrixSenior Software Engineer (Avast)Commented:
The difference between a virtual and non-virtual function is the point at which the binding happens. By binding we mean at which point the actual function that will be called will actually be resolved. In the case of a virtual function C++ uses "late binding" to facilitate virtual dispatch and, this allows for polymorphic behavior, which is what Russ has alluded to in his post, above.

When a function is virtual it behaves polymorphically, which is a fancy way of saying that the function of the static class (the real type of the object instance) will be called, even if you refer to it by a dynamic base class (the currently type of the object instance) reference or pointer. Often (but not always) virtual functions are used to implement interfaces. Other times the base class functions themselves have implementation, but the fact they are virtual allows you to override and specialise their behaviour.

Regarding interfaces, it's like having a specific type of microwave oven. I don't need to know which type you have to know how to use it because all microwave ovens have a timer and a start button and (mostly) work in the same way. As this is the case and because I am already familiar with this interface I can just adjust the timer and press the start button (this is the interface) and I know the microwave will work. You could take this interface from that microwave over and put it one another and it'd still know how to use it. Same reason why I can jump into any car and drive it, because whilst all cars are different the interface is the same.

An example of polymorphism that I like is that animals all make a noise (well, let's assume they do just for this example). I don't need to know what type of animal you have to know it will make a noise. If I have an animal class that has a make virtual noise function the noise made will differ depending on which animal it refers to. In the case of a cat it will meow and in the case of a dog it will bark.

class animal
{
   public:
      virtual void make_noise() = 0;
};

class cat : public animal
{
   public:
      void make_noise() const override { // meow }
};

class dog : public animal
{
   public:
      void make_noise() const override { // bark }
};

animal const & aDog = dog();
animal const & aCat = cat();

aDog.make_noise(); // Barks because this function is virtual on the base
aCat.make_noise(); // Meows because this function is virtual on the base

Open in new window


If the make noise function wasn't virtual the base class version would be called. Not only does this not really make sense as there is no such thing as a generic animal noise, in this case the base class doesn't even implement the virtual function (it is pure) so the code wouldn't even compile. Virtual tells C++ this function is polymorphic. The polymorphic behaviour is achieved by late-binding and late-binding is normally (although it doesn't have to be) implemented using a v-table (a hidden table of function pointers).
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phoffricCommented:
>> This is only important if you're using inheritance.
Agree.

>> The difference between a virtual and non-virtual function is the point at which the binding happens.
Agree, with some semantic clarification. I would recommend changing this sentence to:
One difference between a virtual and non-virtual function is the point at which the dynamic dispatching happens.

>> explain in easy words (for Dummies)
Since there are chapters on this subject, and since evilrix already gave you a number of links to chapters that touch on this subject, I have to agree that this is not an easy request. But, here goes..

In Russ Suter's example, even though the handle_event() method is virtual, I would expect that the compiler optimizer would be able to statically associate the child instance with the handle_event() method since the instance pointer and the method invocation is unambiguous. But, technically, evilrix is correct in that the language is accepting that Suter's code represents dynamic late dispatching. The optimizer saves a few cycles in Suter's code by not having to do that.
int main() {
  parent *p = new child();
  p->handle_event(1);
}

Open in new window

If the pointer, p, were passed into another function, foo(), especially a foo() in another compilable unit, then the compiler might not know whether the pointer is pointing to a base class object, parent, or one of its derived objects. So at the time of compilation, the compiler cannot statically call the desired method. In fact, each time foo() is called, the parent pointer could be pointing to a different class instance - either the parent, or one of its derived class instances.

BTW, as a rule of thumb, it is a good idea to always include a virtual destructor in a class whenever there are virtual methods. But that is another topic.
0
evilrixSenior Software Engineer (Avast)Commented:
>> Agree, with some semantic clarification
Yup, I would agree with your agreement and semantic clarification. Thanks. It's actually amazing how hard it is to articulate these concepts in a "for dummies" kind of way. Thanks, phoffric. :)
0
Ingo FoersterProgrammerAuthor Commented:
Gret, I have understood with first reading. Thank you
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.