Home > Enterprise >  c covariance, call child method
c covariance, call child method

Time:12-02

I create two simple classes by inheritance, and I add a virtual function and the override in the child class.

class Base
{
public:
    virtual Base* getThis() { std::cout << "called Base::getThis()\n"; return this; }
    virtual void func1() { std::cout << "called Base::func1\n"; }
};

class Derived : public Base
{
public:
    Derived* getThis() override { std::cout << "called Derived::getThis()\n";  return this; }
    void func1() override { std::cout << "called Derived::func1\n"; }
    void func2() { std::cout << "called Derived::func2\n"; }
};

With c covariance, I can do this:

int main()
{
    Derived d{};
    Base* b{ &d };
    b->getThis()->func1();
    return 0;
}

Now, I would like to call Derived::func2.

b->getThis()->func2();

The previous code produces the following error: error: 'class Base' has no member named 'func2';

The only solution I have:

dynamic_cast<Derived*>(b->getThis())->func2();

Do we have to use dynamic_cast or static_cast, to call Derived::func2?
Is there another method?

CodePudding user response:

Do we have to use dynamic_cast or static_cast, to call Derived::func2?

Yes.

Is there another method?

Declare a virtual Base::func2 function.


To clarify about covariance, it makes this possible:

Derived d{};
d->getThis()->func2();

Without covariance, Derived* Derived::getThis wouldn't be allowed and thus the above wouldn't work.

CodePudding user response:

Covariant return types are merely a trick that allows the Liskov Substitution Principle to work while varying the return type in the derived class interface slightly. But the point of LSP remains: the base class interface is the interface. It's not a way to make a base class transparently provide stuff that's exclusively part of the derived class.

If you have a pointer/reference to the base class, calling getThis though that pointer/reference will always return a Base*. If you want to get at some derived class-only elements, you must always use some kind of cast.

  • Related