Base class:
class Base
{
public:
virtual int f() const
{
return 1;
}
};
Derived class:
class Derived: public Base
{
public:
void f() const {}
};
Above code throws a "return type is not identical/covariant error".
I've read few discussions on it. This one is similar but they only say that it will break the code if the return types aren't identical/covariants. Override a member function with different return type
Why the behavior I'm expecting doesn't happen?
Expected Behavior: The VPTR in Derived points to Base::f() (I've read incase an override isn't provided for a virtual function, Derived objects will just uses the inherited class version ). Also it hides the name f() so now a call like this:
Derived x;
x.f();
should've called Derived::f() and a call like this:
x.Base::f();
should've called the Base::f() function. This doesn't seem like breaking the code. Incase its upcasted, even then it shouldn't break the code because VPTR for both classes points to the same Base::f()
The only reason I can think of is that such a declaration(same signature and covariant/identical return types) is reserved for overriding virtual methods and we just cannot use it to cause the behavior I'm expecting.
When the compiler encounters the matching signature (arguments, constness), it automatically makes the void f() const
declaration virtual. So the definition of Derived
is interpreted as:
class Derived: public Base
{
public:
virtual void f() const {} // virtual keyword is added
};
It clearly looks like an attempt to override Base::f()
. All this happens because the function signatures match in the Base
and Derived
class. If the signatures didn't match, then only would this be a redefinition in which case it would've hidden the Base::f()
in Derived
class.