Function overriding in Java vs C++
In Java all methods that can be overridden are automatically virtual. There is no opt-in mechanism (virtual
keyword) for it as it is in C++ (and there's no way to opt-out either).
Java behaves as if you had declared base::func2
as
virtual void func2(){
printf(" I am in base:func2() \n");
}
In which case your program would have printed "I am in derived:func2()"
.
How the
func2()
class binding being inferred?
Whichfun2()
should be called and how it is determined.
For non-virtual methods (C++ methods without virtual
modifier) it is the static type that determines which method to call. The static type of the variable is determined by the variable declaration and does not depend on how the code is executed.
For virtual methods (C++ methods with the virtual
modifier and all Java methods) it is the runtime type that determines which method to call. The runtime type is the type of the actual object in runtime.
Example: If you have
Fruit f = new Banana();
the static type of f
is Fruit
and the runtime type of f
is Banana
.
If you do f.someNonVirtualMethod()
the static type will be used and Fruit::someNonVirtualMethod
will be called. If you do f.someVirtualMethod()
the runtime type will be used and Banana::someVirtualMethod
will be called.
The underlying implementation for how the compiler achieves this is basically implementation dependent, but typically a vtable is used. For details refer to
- How Vtable of Virtual functions work
- How does virtual method invocation work in C++?
- Mechanism of Vptr and Vtable in C++
If no, how
this
is able to reach to the function inbase
class?void func1(){ func2(); }
If you're wondering why func2()
here calls base
's func2
it is because
A) You're in the scope of base
which means that the static type of this
is base
, and
B) func2
in base
is not virtual, so it is the static type that decides which implementation to call.