views:

164

answers:

6

What is the purpose of using the reserved word virtual in front of functions? If I want a child class to override a parent function, I just declare the same function such as "void draw(){}".

class Parent{ public:   void say(){ std::cout << "1"; }};
class Child : public Parent{public:void say(){ std::cout << "2"; } };
int main()
{
    Child* a = new Child();
    a->say();
    return 0;
}

The output is 2.

So again, why would the reserved word "virtual" be necessary in the header of say() ?

Thanks a bunch.

+1  A: 

When you use the keyword virtual, a virtual function table is created to locate the correct methods in an instance. Then, even if the derived instance is pointed to by a base class pointer, it will still find the correct implementation of the method.

Amardeep
+11  A: 

If the function were virtual, then you could do this and still get the output "2":

Parent* a = new Child();
a->say();

This works because a virtual function uses the actual type whereas a non-virtual function uses the declared type. Read up on polymorphism for a better discussion of why you'd want to do this.

Donnie
+6  A: 

Try it with:

Parent *a = new Child();
Parent *b = new Parent();

a->say();
b->say();

Without virtual, both with print '1'. Add virtual, and the child will act like a Child, even though it's being referred to via a pointer to a Parent.

Jerry Coffin
A: 

This is a very important aspect of c++ programming-- almost every interview I've been to, I get asked this question.

What happens if you change your main to: int main() { Parent* a = new Child(); a->say(); return 0; }

Also, it's worth understanding what a vtable is.

+4  A: 

If you do not use the virtual keyword you are not overriding, but rahter defining an unrelated method in the derived class that will hide the base class method. That is, without the virtual, Base::say and Derived::say are unrelated --besides the name coincidence.

When you use the virtual keyword (required in the base, optional in the derived class), you are telling the compiler that classes that derive from this base will be able to override the method. In that case, Base::say and Derived::say are considered overrides of the same method.

When you use a reference or pointer to a base class to call a virtual method, the compiler will add the appropriate code so that the final overrider is called (the override in the most derived class that defines the method in the hierarchy of the concrete instance in use). Note that if you do not use references/pointer but local variables, the compiler can resolve the call and it does not need to use the virtual dispatch mechanism.

David Rodríguez - dribeas
A: 

This is the classic question of how polymorphism works I think. The main idea is that you want to abstract the specific type for each object. In other words: You want to be able to call the Child instances without knowing it's a child!

Here is an example: Assuming you have class "Child" and class "Child2" and "Child3" you want to be able to refer to them through their base class (Parent).

Parent[3] parents; parents[0] = new Child(); parents[1] = new Child2(); parents[2] = new Child3();

for (int i=0;i<3;++i) parents[i]->say();

As you can imagine, this is very powerful. It let's you extend the Parent as many times as you want and functions that take a Parent pointer will still work. For this to work as others mention you need to declare the method as virtual.

krolth