More C++ Idioms/Covariant Return Types

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Covariant Return Types
[edit | edit source]

Intent[edit | edit source]

Avoid unnecessary casting of the derived value returned from an overridden method in a derived class.

Also Known As[edit | edit source]

Motivation[edit | edit source]

In C++ a base class determines the method signatures of virtual functions that derived classes might override. The type of the return value in the overridden function is generally same as that of the base class's function. However, this can be limiting if the type returned by the overridden function is substitutable (sub-class) for the type of the base function. Consider the following example.

class Base {
  public:
    virtual Base * clone() const {
      return new Base(*this); 
    }
};
class Derived : public Base {
  public:
    virtual Base * clone() const override {
      return new Derived(*this); 
    }
};
Derived *d1 = new Derived();
Base * b = d1->clone();
Derived *d2 = dynamic_cast<Derived *>(b);
if(d2) {
  // Use d2 here.
}

The caller of clone knows that the run-time type of the object returned by the function is Derived. However, a dynamic_cast is necessary to downcast the Base pointer to Derived if functions specific to Derived are to be used.

Solution and Sample Code[edit | edit source]

C++ allows the derived type to implement an overridden function with return type that is a (pointer to a) sub-type of the return type of the base function. Here's an updated example.

class Base {
  public:
    virtual Base * clone() const {
      return new Base(*this); 
    }
};
class Derived : public Base {
  public:
    virtual Derived * clone() const override {
      return new Derived(*this); 
    }
};
Derived *d1 = new Derived();
Derived *d2 = d1->clone();
if(d2) {
  // Use d2 here.
}

This alternative is direct and saves unnecessary casts.

Known Uses[edit | edit source]

Related Idioms[edit | edit source]

References[edit | edit source]