Search code examples
c++inheritanceinterfaceabstract-classpure-virtual

Override function that return base type


I have two classes. Base class Parent and derived class Child. Class Parent has pure virtual function that returns its class type. How can I override it in derived class?

class Parent
{
    public:
        virtual Parent* OverrideMe(Parent* func) = 0;
};

class Child : public Parent
{
    public:
        Child* OverrideMe(Child* func) override;
};

I tried Child* OverrideMe(Child* func) override; but I end up with error that it does not override a base class member.


Solution

  • If C++ had full covariance and contravariance support, the correct relationship would be contravariant in input and covariant in output. Namely:

    struct Organism { };
    
    struct Animal : Organism {
        virtual Animal* OverrideMe(Animal* ) = 0;
    };
    
    struct Dog : Aniaml {
        Dog* OverrideMe(Organism* ) override { ... }
        ↑↑↑             ↑↑↑↑↑↑↑↑
        covariant       contravariant
    };
    

    It seems a little unintuitive, but it does make sense. If you are expecting a Animal*, you should be able to handle anything that is a Animal* (of which a Dog* qualifies). Conversely, if you are doing some operation on a Animal*, you just need an operation that can take a Animal* - and an operation that takes an Organism* qualifies on that front.

    Note that if the input was covariant, that would break the type system. Consider something like;

    Animal* a = new Dog;
    a->OverrideMe(new Cat);
    

    If Dog::OverrideMe were allowed to take a Dog*, that would fail - a Cat* is not a Dog*! So it is allowed to take an Animal* ... or anything more generic than that (e.g. Organism*), since all of those work fine.

    C++ does not have support for contravariance in input, only covariance in output. So you could write either:

    Dog* OverrideMe(Animal* ) override { ... }
    

    or:

    Animal* OverrideMe(Animal* ) override { .... }
    

    but nothing else.