Don’t forget that virtual
I am not really a C++ programmer. I usually code in C, and I think all C++ I’ve ever written involved a couple of vectors and maybe one or two classes. So what I’m writing here is certainly old news for C++ programmers.
The other day, while I was reading this essay about the Liskov Substitution Principle, I was intrigued by a situation presented in page 4, which deals with class inheritance and method overriding.
Methods that can be overriden must be declared virtual in C++. I really didn’t know about that. I am used to Java’s behaviour, which I illustrate below:
/* * A.java */ public class A { public void bar() { System.out.println("bar"); } } /* * B.java */ public class B extends A { public void bar() { System.out.println("Bar!"); } } /* * C.java */ public class C { public void call(A o) { o.bar(); } } /* * Main.java */ public class Main { public static void main(String [] args) { A a = new A(); B b = new B(); C c = new C(); c.call(a); c.call(b); } }
The code above will produce the following output:
bar Bar!
If I wanted to do the same thing in C++, I would have to write it this way:
#include <iostream> class A { public: A() {} virtual ~A() {} virtual void bar() { std::cout << "bar" << std::endl; } }; class B : public A { public: B() {} virtual ~B() {} void bar() { std::cout << "Bar!" << std::endl; } }; class C { public: C() {}; virtual ~C() {}; void call(A &o) { o.bar(); } }; int main(int argc, char *argv[]) { A a; B b; C c; c.call(a); c.call(b); return 0; }
The output will be the same as the Java program, but pay attention to the virtual modifier placed before the declaration of the bar method in A. If I remove it, the output will be:
bar bar
Even though B declares a method called bar, it is completely shadowed by the implementation inherited from A. In my opinion, Java’s behaviour is a lot more intuitive. I wonder how many people might have spend hours, maybe days, looking for a bug in a C++ program when the problem was that a method was not declared virtual and method calls weren’t occuring as expected.
I talked about this with Otávio, and he found out C# has a similar characteristic. In C#, a method must be declared as virtual for its subclasses to override it AND the subclasses must use override when overriding the method. Here’s the code he provided me:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Alice { public virtual void sayHello() { Console.WriteLine("Hello, world"); } } class Bob : Alice { public override void sayHello() { Console.WriteLine("Hello, world!"); } } class Echo { public void say(Alice toto) { toto.sayHello(); } } class Program { static void Main(string[] args) { Alice a = new Alice(); Bob b = new Bob(); Echo e = new Echo(); e.say(a); e.say(b); } } }
Some people argue that this makes code clearer, but I’m not convinced. Why not make overriding implicit?

I do agree that virtual should not be necessary, and most modern languages such as PHP does not require it for override.