Java – need to declare virtual functions as such

cjavaobject-orientedvirtual-functions

Example:
We have a base class Base and three subclasses which all implement their own version of doSomething().

In an intermediate function f(Base b), we want to call the relevant version of doSomething() depending on which object has been passed.

Why do we need to declare doSomething as a virtual function in Base? Surely b now points to the correct object so that when we call b.doSomething, we know which method needs to be called.

Side Question: If b is simply pointing to an object, why does it even need a type?

Oddly enough, this once made perfect sense but I'm starting to have doubts, and questions are arising…

Best Answer

Because virtual functions have a runtime performance cost, and part of the philosophy of C++ is "you don't pay for what you don't use."

Specifically, virtual methods have to dereference a pointer to find out where the correct method is for the specific object they were called on. One pointer dereference per call may not sound like a lot, but this also prevents the function from ever being inlined, and you have to refer to the object itself via pointer or reference for a virtual function call to work in the first place (otherwise you get "object slicing" which may have wider repercussions).

Usually, this is indeed not a very big cost, which is why some languages like Java can get away with things like "making all class variables references" and "making all methods virtual by default", presumably in the hopes of creating a simpler language for applications that can be developed without a detailed understanding of how each language feature is typically implemented.

Side Question: If "b" is simply pointing to an object, why does it even need a type?

If you really want to, you can use void*, which is effectively a pointer with no type. But you shouldn't normally do that because properly typed pointers add a modicum of type safety. And most of the time, you should be using smart pointers like std::unique_ptr which are even safer since they automagically deallocate the memory they point to when you're done with them.