13

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?

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
kravemir
  • 10,636
  • 17
  • 64
  • 111
  • possible duplicate of [C++ Virtual/Pure Virtual Explained](http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained) – Harald Scheirich Jun 18 '11 at 16:41
  • @Harald: Nope. Different topic. – Xeo Jun 18 '11 at 16:46
  • But i'm asking about usage of that keyword. Not about abstract virtual method. – kravemir Jun 18 '11 at 16:47
  • Virtual keyword in derived class is optional but it's better to skip it. Otherwise, if you have a lot of derived classes and you want to make one of the inherited methods virtual, you would have to add virtual keyword in all of these derived classes to this method. – cpp Aug 14 '13 at 12:22

4 Answers4

13

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.
void-pointer
  • 14,247
  • 11
  • 43
  • 61
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    I know that virtual is necessary when declaring method that can be overridden. I've asked about using this keyword when overriding method, not declaring. – kravemir Jun 18 '11 at 16:41
  • 1
    @Miro: I don't follow. You override a function by declaring another one that overrides it. Either way, at the very least my final paragraph answers your question. – Lightness Races in Orbit Jun 18 '11 at 16:42
8

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.

Xeo
  • 129,499
  • 52
  • 291
  • 397
6

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()
    {
        /*...*/
    };
};
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
0

Extending on Light Races answer, maybe this will help some people to see what it is doing.

struct Base {
public:
    void foo() {
        printf_s("Base::foo\n");
    }
};

struct Derived : Base {
    void foo() {
        printf_s("Derived::foo\n");
    }
};

struct BaseVirtual {
public:
    virtual void foo() {
        printf_s("BaseVirtual::foo\n");
    }
};

struct DerivedVirtual : BaseVirtual {
    virtual void foo() {
        printf_s("DerivedVirtual::foo\n");
    } 
};

Derived d;
d.foo(); // Outputs: Derived::foo

Base& b = d;
b.foo(); // Outputs: Base::foo

DerivedVirtual d2;
d2.foo(); // Outputs: DerivedVirtual::foo

BaseVirtual& b2 = d2;
b2.foo(); // Outputs: DerivedVirtual::foo

Chris0
  • 475
  • 5
  • 6