Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the virtual keyword mean when overriding a method?

What does the keyword virtual do when overriding a method? I'm not using it and everything works fine.

Does every compiler behave the same in this regard?

Should I use it or not?

like image 483
kravemir Avatar asked Jun 18 '11 16:06

kravemir


3 Answers

You cannot override a member function without it.

You can only hide one.

struct Base {
   void foo() {}
};

struct Derived : Base {
   void foo() {}
};

Derived::foo does not override Base::foo; it simply hides it because it has the same name, such that the following:

Derived d;
d.foo();

invokes Derived::foo.

virtual enables polymorphism such that you actually override functions:

struct Base {
   virtual void foo() {}
};

struct Derived : Base {
   virtual void foo() {} // * second `virtual` is optional, but clearest
};

Derived d;
Base& b = d;
b.foo();

This invokes Derived::foo, because this now overrides Base::foo — your object is polymorphic.

(You also have to use references or pointers for this, due to the slicing problem.)


  • Derived::foo doesn't need to repeat the virtual keyword because Base::foo has already used it. This is guaranteed by the standard, and you can rely on it. However, some think it best to keep that in for clarity.
like image 69
Lightness Races in Orbit Avatar answered Nov 10 '22 17:11

Lightness Races in Orbit


A virtual method in the base class will cascade through the hierarchy, making every subclass method with the same signature also virtual.

class Base{
public:
  virtual void foo(){}
};

class Derived1 : public Base{
public:
  virtual void foo(){} // fine, but 'virtual' is no needed
};

class Derived2 : public Base{
public:
  void foo(){} // also fine, implicitly 'virtual'
};

I'd recommend writing the virtual though, if for documentation purpose only.

like image 45
Xeo Avatar answered Nov 10 '22 17:11

Xeo


When a function is virtual, it remains virtual throughout the hierarchy, whether or not you explicitly specify each time that it is virtual. When overriding a method, use virtual in order to be more explicit - no other difference :)

class A
{
    virtual void f() 
    {
      /*...*/
    };
};

class B:public A;
{
    virtual void f()  //same as just void f()
    {
        /*...*/
    };
};
like image 6
Armen Tsirunyan Avatar answered Nov 10 '22 15:11

Armen Tsirunyan