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.
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.
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.
If you don't override a pure virtual function in a derived class, that derived class becomes abstract: class D2 : public Base {
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With