When I write like this:
class A {
public: virtual void foo() = 0;
}
class B {
public: void foo() {}
}
…B::foo() becomes virtual as well. What is the rationale behind this? I would expect it to behave like the final keyword in Java.
Add: I know that works like this and how a vtable works 🙂 The question is, why C++ standard committee did not leave an opening to call B::foo() directly and avoid a vtable lookup.
The standard does leave an opening to call B::foo directly and avoid a table lookup:
Output:
So you can get the behaviour you say you expect as follows:
Now callers should use bar instead of foo. If they have a C*, then they can cast it to A*, in which case
barwill callC::foo, or they can cast it to B*, in which casebarwill callB::foo. C can override bar again if it wants, or else not bother, in which case callingbar()on a C* callsB::foo()as you’d expect.I don’t know when anyone would want this behaviour, though. The whole point of virtual functions is to call the same function for a given object, no matter what base or derived class pointer you’re using. C++ therefore assumes that if calls to a particular member function through a base class are virtual, then calls through derived classes should also be virtual.