Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 'virtual' optional for overridden methods in derived classes?

When a method is declared as virtual in a class, its overrides in derived classes are automatically considered virtual as well, and the C++ language makes this keyword virtual optional in this case:

class Base {
    virtual void f();
};
class Derived : public Base {
    void f(); // 'virtual' is optional but implied.
};

My question is: What is the rationale for making virtual optional?

I know that it is not absolutely necessary for the compiler to be told that, but I would think that developers would benefit if such a constraint was enforced by the compiler.

E.g., sometimes when I read others' code I wonder if a method is virtual and I have to track down its superclasses to determine that. And some coding standards (Google) make it a 'must' to put the virtual keyword in all subclasses.

like image 933
squelart Avatar asked Jun 03 '10 07:06

squelart


People also ask

Is it mandatory to override virtual method in derived class?

It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used. A class may have virtual destructor but it cannot have a virtual constructor.

Should overridden functions be virtual?

When you override a function you don't technically need to write either virtual or override . The original base class declaration needs the keyword virtual to mark it as virtual. In the derived class the function is virtual by way of having the ¹same type as the base class function.

What happens when a derived class does not override a virtual function?

If you don't override a pure virtual function in a derived class, that derived class becomes abstract: class D2 : public Base {

Why does virtual keyword used during new class derivation?

Adding the "virtual" keyword is good practice as it improves readability , but it is not necessary. Functions declared virtual in the base class, and having the same signature in the derived classes are considered "virtual" by default.


Video Answer


2 Answers

Yeah, it would really be nicer to make the compiler enforce the virtual in this case, and I agree that this is a error in design that is maintained for backwards compatibility.

However there's one trick that would be impossible without it:

class NonVirtualBase {
  void func() {};
};

class VirtualBase {
  virtual void func() = 0;
};

template<typename VirtualChoice>
class CompileTimeVirtualityChoice : public VirtualChoice {
  void func() {}
};

With the above we have compile time choice wether we want virtuality of func or not:

CompileTimeVirtualityChoice<VirtualBase> -- func is virtual
CompileTimeVirtualityChoice<NonVirtualBase> -- func is not virtual

... but agreed, it's a minor benefit for the cost of seeking a function's virtuality, and myself, I always try to type virtual everywhere where applicable.

like image 126
Kornel Kisielewicz Avatar answered Oct 28 '22 00:10

Kornel Kisielewicz


As a related note, in C++0x you have the option of enforcing being explicit with your overrides via the new attribute syntax.

struct Base {
  virtual void Virtual();
  void NonVirtual();
};

struct Derived [[base_check]] : Base {
  //void Virtual(); //Error; didn't specify that you were overriding
  void Virtual [[override]](); //Not an error
  //void NonVirtual [[override]](); //Error; not virtual in Base
  //virtual void SomeRandomFunction [[override]](); //Error, doesn't exist in Base
};

You can also specify when you intend to hide a member via the [[hiding]] attribute. It makes your code somewhat more verbose, but it can catch a lot of annoying bugs at compile time, like if you did void Vritual() instead of void Virtual() and ended up introducing a whole new function when you meant to override an existing one.

like image 38
Dennis Zickefoose Avatar answered Oct 28 '22 00:10

Dennis Zickefoose