Missing 'virtual' qualifier in function declarations - c++

Whilst trawling through some old code I came across something similar to the following:
class Base
{
public:
virtual int Func();
...
};
class Derived : public Base
{
public:
int Func(); // Missing 'virtual' qualifier
...
};
The code compiles fine (MS VS2008) with no warnings (level 4) and it works as expected - Func is virtual even though the virtual qualifier is missing in the derived class. Now, other than causing some confusion, are there any dangers with this code or should I change it all, adding the virtual qualifier?

The virtual will be carried down to all overriding functions in derived classes. The only real benefit to adding the keyword is to signify your intent a casual observer of the Derived class definition will immediately know that Func is virtual.
Even classes that extend Derived will have virtual Func methods.
Reference: Virtual Functions on MSDN. Scroll down the page to see
The virtual keyword can be used when
declaring overriding functions in a
derived class, but it is unnecessary;
overrides of virtual functions are
always virtual.

Here's an interesting consequence of not needing to declare overriding functions virtual:
template <typename Base>
struct Derived : Base
{
void f();
};
Whether Derived's f will be virtual depends on whether Derived is instantiated with a Base with a virtual function f of the right signature.

Someone told me once that very old C++ compilers, not conforming to the spec, require virtual to be set for all subclasses. That's not an issue anymore.

One danger of following this practice is that people may not realise they need the virtual keyword on functions which are intended to be virtual. This is most likely to be people coming from languages where there is no concept of non-virtual functions (eg: Java, REALbasic). As a corollary, you can't tell when virtual has been deliberately omitted because a function is supposed to be non-virtual.
I suspect some code analysis tools may also not be smart enough to pick up the inherited virtuality.

Related

non-virtual destructors in c++ with override

Yes I have seen a lots of posts about using the keywords virtual and override for destructors in C++. I also think I understand the usage:
if a base class has a virtual destructor and a derived class overrides it, if the signatures are different, the program will not compile due to override.
However I am wondering - or I have seen it also several times in someones code, that it is used like this:
class Base
{
public:
~Base();
};
class Derived : public Base
{
public:
~Derived() override;
};
Does this override on a destructor of a non-virtual function in the base class actually has any impact on the program / compiling or anything? Or is it just used wrongly in that case?
You code doesn't compile because Base::~Base is not virtual.
Oh ok, maybe I have overseen this: if the Base class derives from
another class, say SuperBase class - which has a virtual destructor,
then the destructor of Base would be virtual without using the keyword
right?
Correct. If a method is virtual in a base class, then the method in the child class with the same name and same signature will also be implicitly virtual. virtual keyword can be omitted.
A good practice is to always use the keyword override on a method intended to override. This has two big advantages: it makes it clear to a human reader that the method is virtual and overrides and it avoid some bugs where the method is indented to override, but it silently doesn't (e.g. const mismatch).
Destructors are a special case in the sense that that they override a parent virtual destructor, even if they have different names.

Isn't 'virtual' keyword redundant when 'override' or 'final' specifiers are used?

Let's say I have the following base class:
class Base {
public:
virtual void f() {};
};
If I want to write a class that will override the f() and will not allow to override it to it's derived classes can write it using following approaches:
Approach 1:
class Derived : public Base {
public:
virtual void f() override final {};
};
Approach 2:
class Derived : public Base {
public:
void f() final {};
};
Approach 1 is a fully detailed when Approach 2 more compact and final still says that f() is actually virtual and overrides the base class method.
Which one approach is more appropriate?
In "Approach 1", the virtual is indeed redundant. 'override' is a special identifier that shows the reader of the code that a virtual function is being overridden, while also being a hint for the compiler to verify that it actually is. The base class has already stated that the function is virtual, so there is no need to do that again.
When not using the 'final' keyword, it is good practice to have a 'virtual', simply to maintain readability. Approach 2 is the best-practice notation in this case.
This kinda comes down to the style that is used in your environment, but final definitly does not imply override final.
class Derived : public Base {
public:
void f() override final {};
};
Maybe that way? virtual keyword is not needed in derived class, override and final both give you a compiler error if there is no method to override, but you or someone else may want to remove final keyword in future then override give you a pure intention of your method behavior.
This is very out-dated now as C++11 is widely available but as an early adopter of C++11 I used #defines for override and final to backport my code to C++03 and earlier.
I doubt this is required on any modern platforms now but you never know.
I still find it aesthetically painful that the override and virtual keywords are not both on the same side.
This question and answer are a better reference than the current one.

C++ "virtual" keyword for functions in derived classes. Is it necessary?

With the struct definition given below...
struct A {
virtual void hello() = 0;
};
Approach #1:
struct B : public A {
virtual void hello() { ... }
};
Approach #2:
struct B : public A {
void hello() { ... }
};
Is there any difference between these two ways to override the hello function?
They are exactly the same. There is no difference between them other than that the first approach requires more typing and is potentially clearer.
The 'virtualness' of a function is propagated implicitly, however at least one compiler I use will generate a warning if the virtual keyword is not used explicitly, so you may want to use it if only to keep the compiler quiet.
From a purely stylistic point-of-view, including the virtual keyword clearly 'advertises' the fact to the user that the function is virtual. This will be important to anyone further sub-classing B without having to check A's definition. For deep class hierarchies, this becomes especially important.
The virtual keyword is not necessary in the derived class. Here's the supporting documentation, from the C++ Draft Standard (N3337) (emphasis mine):
10.3 Virtual functions
2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
No, the virtual keyword on derived classes' virtual function overrides is not required. But it is worth mentioning a related pitfall: a failure to override a virtual function.
The failure to override occurs if you intend to override a virtual function in a derived class, but make an error in the signature so that it declares a new and different virtual function. This function may be an overload of the base class function, or it might differ in name. Whether or not you use the virtual keyword in the derived class function declaration, the compiler would not be able to tell that you intended to override a function from a base class.
This pitfall is, however, thankfully addressed by the C++11 explicit override language feature, which allows the source code to clearly specify that a member function is intended to override a base class function:
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int) override; // ill-formed - doesn't override a base class method
};
The compiler will issue a compile-time error and the programming error will be immediately obvious (perhaps the function in Derived should have taken a float as the argument).
Refer to WP:C++11.
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.
There is no difference for the compiler, when you write the virtual in the derived class or omit it.
But you need to look at the base class to get this information. Therfore I would recommend to add the virtual keyword also in the derived class, if you want to show to the human that this function is virtual.
The virtual keyword should be added to functions of a base class to make them overridable. In your example, struct A is the base class. virtual means nothing for using those functions in a derived class. However, it you want your derived class to also be a base class itself, and you want that function to be overridable, then you would have to put the virtual there.
struct B : public A {
virtual void hello() { ... }
};
struct C : public B {
void hello() { ... }
};
Here C inherits from B, so B is not the base class (it is also a derived class), and C is the derived class.
The inheritance diagram looks like this:
A
^
|
B
^
|
C
So you should put the virtual in front of functions inside of potential base classes which may have children. virtual allows your children to override your functions. There is nothing wrong with putting the virtual in front of functions inside of the derived classes, but it is not required. It is recommended though, because if someone would want to inherit from your derived class, they would not be pleased that the method overriding doesn't work as expected.
So put virtual in front of functions in all classes involved in inheritance, unless you know for sure that the class will not have any children who would need to override the functions of the base class. It is good practice.
There's a considerable difference when you have templates and start taking base class(es) as template parameter(s):
struct None {};
template<typename... Interfaces>
struct B : public Interfaces
{
void hello() { ... }
};
struct A {
virtual void hello() = 0;
};
template<typename... Interfaces>
void t_hello(const B<Interfaces...>& b) // different code generated for each set of interfaces (a vtable-based clever compiler might reduce this to 2); both t_hello and b.hello() might be inlined properly
{
b.hello(); // indirect, non-virtual call
}
void hello(const A& a)
{
a.hello(); // Indirect virtual call, inlining is impossible in general
}
int main()
{
B<None> b; // Ok, no vtable generated, empty base class optimization works, sizeof(b) == 1 usually
B<None>* pb = &b;
B<None>& rb = b;
b.hello(); // direct call
pb->hello(); // pb-relative non-virtual call (1 redirection)
rb->hello(); // non-virtual call (1 redirection unless optimized out)
t_hello(b); // works as expected, one redirection
// hello(b); // compile-time error
B<A> ba; // Ok, vtable generated, sizeof(b) >= sizeof(void*)
B<None>* pba = &ba;
B<None>& rba = ba;
ba.hello(); // still can be a direct call, exact type of ba is deducible
pba->hello(); // pba-relative virtual call (usually 3 redirections)
rba->hello(); // rba-relative virtual call (usually 3 redirections unless optimized out to 2)
//t_hello(b); // compile-time error (unless you add support for const A& in t_hello as well)
hello(ba);
}
The fun part of it is that you can now define interface and non-interface functions later to defining classes. That is useful for interworking interfaces between libraries (don't rely on this as a standard design process of a single library). It costs you nothing to allow this for all of your classes - you might even typedef B to something if you'd like.
Note that, if you do this, you might want to declare copy / move constructors as templates, too: allowing to construct from different interfaces allows you to 'cast' between different B<> types.
It's questionable whether you should add support for const A& in t_hello(). The usual reason for this rewrite is to move away from inheritance-based specialization to template-based one, mostly for performance reasons. If you continue to support the old interface, you can hardly detect (or deter from) old usage.
I will certainly include the Virtual keyword for the child class, because
i. Readability.
ii. This child class my be derived further down, you don't want the constructor of the further derived class to call this virtual function.

Using 'virtual' in derived class

I saw code in a derived class recently in which the programmer put virtual in front of the functions overridden. Is this common? I thought it was very odd and it kind of caught me off guard.
Edit: I'm not asking what virtual does, I'm asking why someone would put virtual in a derived class that is already overriding virtual functions in its base class.
EX:
class B {
public:
virtual void foo();
....
};
class D : public B {
public:
virtual void foo(); // could have just put void foo();
...
};
virtual is needed for overrideable functions at the highest (least derived) level. It is optional, but harmless at lower (more derived) levels. It's good for self-documenting the code.
These answers (and this practice) are outdated. As of C++11, you should use the override keyword to explicitly specify that a virtual function overrides another virtual function. Your compiler will throw an error if you try to override something that isn't a virtual function in the base class!
It is very common. Many style guides recommend it, e.g. Google.
The purpose is to enhance readability of the code.
I don't see anything odd in it. In many cases (if not most of the time) programmers create the declaration of the overriding function in the derived class by copy-pasting it from the base class. There's no point in spending the additional effort to manually remove the redundant virtual specifier. Moreover, the explicit virtual makes it easier to see which functions are virtual.
Another way to enhance readability is to use something like this:
class B {
public:
virtual void foo();
....
};
class D : public B {
public:
/*override*/ void foo();
...
};
I'll assume that you know the purpose of the virtual keyword but wondering why it suddenly appears in a subtype. If I am mistaken, my answer probably won't make much sense but any C++ reference will do.
It is perfectly legal to put virtual in a derived class. As a result, if you have a reference or pointer to that class or any of its subclasses, invocations of this function would be bound dynamically based on the runtime type.
While legal, however, it is not considered good design to have a nonvirtual method in the base class and virtual in an overridden version.
One reason is that you could have an instance of the derived class, and then one pointer to base and one pointer to the derived, and have both pointers aiming at this instance. Invoking the same function on each pointer would then have a different result, since invoking on the pointer declared with the base class would target the definition in the base class.
This will help if future derivations also. If someone wants to derive class D and have virtual functions, then its easy to understand

Should I declare all functions virtual in a base class?

When I declare a base class, should I declare all the functions in it as virtual, or should I have a set of virtual functions and a set of non-virtual functions which I am sure are not going to be inherited?
A function only needs to be virtual iff a derived class will implement that function in a different way.
For example:
class Base {
public:
void setI (int i) // No need for it to be virtual
{
m_i = i;
}
virtual ~Base () {} // Almost always a good idea
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return false;
}
private:
int m_i;
};
class Derived1 : public Base {
public:
virtual ~Derived () {}
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return true;
}
};
As a result, I would error the side of not having anything virtual unless you know in advance that you intend to override it or until you discover that you require the behaviour. The only exception to this is the destructor, for which its almost always the case that you want it to be virtual in a base class.
You should only make functions you intend and design to be overridden virtual. Making a method virtual is not free in terms of both maintenance and performance (maintenance being the much bigger issue IMHO).
Once a method is virtual it becomes harder to reason about any code which uses this method. Because instead of considering what one method call would do, you must consider what N method calls would do in that scenario. N represents the number of sub classes which override that method.
The one exception to this rule is destructors. They should be virtual in any class which is intended to be derived from. It's the only way to guarantee that the proper destructor is called during deallocation.
The non-virtual interface idiom (C++ Coding Standards item 39) says that a base class should have non-virtual interface methods, allowing the base class to guarantee invariants, and non-public virtual methods for customization of the base class behaviour by derived classes. The non-virtual interface methods call the virtual methods to provide the overridable behaviour.
I tend to make only the things I want to be overridable virtual. If my initial assumptions about what I will want to override turn out to be wrong, I go back and change the base class.
Oh, and obviously always make your destructor virtual if you're working on something that will be inherited from.
If you are creating a base class ( you are sure that somebody derives the class ) then you can do following things:
Make destructor virtual (a must for base class)
Define methods which should be
derived and make them virtual.
Define methods which need not be ( or
should not be) derived as
non-virtual.
If the functions are only for derived
class and not for base class then mark
them as protected.
Compiler wouldn't know which actual piece of code will be run when pointer of base type calls a virtual function. so the actual piece of code that would be run needs to be evaluated at run-time according to which object is pointed by base class pointer. So avoid the use of virtual function if the function is not gonne be overriden in an inherited class.
TLDR version:
"you should have a set of virtual functions and a set of non-virtual functions which you are sure are not going to be inherited." Because virtual functions causes a performance decrease at run-time.
The interface functions should be, in general, virtual. Functions that provide fixed functionality should not.
Why declare something virtual until you are really overriding it? I believe it's not a question of being sure or not. Follow the facts: is it overriden somewhere? No? Then it must not be virtual.