c++inheritancepolymorphismoverridingvptr

Why using a different return type in virtual function declaration throws an error instead of resulting in a redefinition?


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.


Solution

  • 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.