1

I have an abstract class A that returns a pointer of its type. Then I have a derived class B which implements the methods defined in class A. I want the methods defined in class B to return class B pointers. Any idea how to do that?

class A {
    public:
        virtual A* foo() {}
}
class B: public A {}

B *x = new B();
x->foo();  // This should return B*

Do I need to override foo in B to return B*? Is there some better way ?

yash vaidya
  • 9
  • 1
  • 4

1 Answers1

5

I can think of 2 ways to achieve that:

1. Overriding (requires foo to be virtual)

This can only be done if the return types are covariant, but if B inherits from A then B is covariant to A.

class A {
    public:
        virtual A* foo() { return new A; }
};
class B: public A {
    public:
        B* foo() override { return new B; }
};

2. Curiously Recurring Template Pattern (CRTP)

You can provide child class as template parameter for the base class.

template <typename T>
class A {
    public:
        T* foo() { return new T; }
};
class B: public A<B> {
    // only B* foo() exists
};
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • In the case of CRTP you probably also need an additional non-template base class from which `A` inherits. Otherwise, without a common base type, there is no benefit to inheritance or polymorphism and they should just use `B` directly. – François Andrieux Feb 02 '21 at 18:27
  • @FrançoisAndrieux This is interesting. Do you have an example where the CRTP class inherits from a common base class? – shargors Feb 02 '21 at 19:04
  • 1
    @shargors Not off hand. It's hard enough to invent a plausible use case for CRTP on the spot, it is harder to come up with a plausible use case for that *and* additional requirements. But it is necessary if various specializations are expected to used polymorphically. – François Andrieux Feb 02 '21 at 19:16
  • Will CRTP work for multilevel inheritance A -> B -> C. ? – yash vaidya Feb 03 '21 at 17:43
  • @Yksisarvinen Will CRTP work for multilevel inheritance A -> B -> C. ? – yash vaidya Feb 03 '21 at 17:49