简体   繁体   中英

Override virtual function with different return type

I understand that virtual functions can be overridden using return type if the return type is covariant.

But can we use the changed return type? or the return type will implicitly be converted to base class' function's return type like B* to A* here.

class A
{
    public:
    virtual A *func()
    {
        A *obj=0;
        return obj;
    }
};

class B:public A
{
    public:
    virtual B *func()
    {
       B *obj =0;
       return obj;
    }
};

int main()
{
    A *obj = new B();
    obj->func();              // does in fact call B::func()
    B *obj2 = obj->func();    // throws error: invalid conversion from 'A*' to 'B*'

    return 0;
}

It seems obj->func() is returning A* and not B* and hence i get this conversion error.

Static type checking must still hold, even if the dynamic type does something slightly different in the implementation. So it really depends on the static type of the object being pointed at. When you call the virtual member on an A* , the return type is specified as A* .

If you were to call it on a B* , the return type of the function would have been (statically) a B* .

B *obj = new B();
obj->func();              
B *obj2 = obj->func();   // Okay now

Whenever you deal with run-time polynorphism in C++, it's the static type of the objects that determines the interface.

Static type of obj is A* so obj->func() would use A *A::func() declaration:

  • return type ( A* )
  • access specifier ( public: )
  • default argument (n/a)

Dynamic type is B* , so it will call B* B::func() and thanks to covariant type would in fact convert its return value in A* .

Types in an inheritance hierarchy can implicitly be downcasted, in your example from B to A , and this allows for covariant return types, too. But you try to implicitly upcast,

B *obj2 = obj->func();

which cannot work because obj is an A instance, and func() is statically bound to the signature that A provides. If it's essential to get a B* from A::func() you can go with an explicit cast

auto *obj2 = dynamic_cast<B*>(obj->func());

but that's kind of a bad pattern, as it compromises the whole point of polymorphism.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM