When is C++ covariance the best solution?

anon picture anon · Aug 11, 2009 · Viewed 12.9k times · Source

This question was asked here a few hours ago and made me realise that I have never actually used covariant return types in my own code. For those not sure what covariance is, it's allowing the return type of (typically) virtual functions to differ provided the types are part of the same inheritance hierarchy. For example:

struct A {
   virtual ~A();
   virtual A * f();
   ...
};

struct B : public A {
   virtual B * f();
   ...
};

The different return types of the two f() functions are said to be covariant. Older versions of C++ required the return types to be the same, so B would have to look like:

struct B : public A {
   virtual A * f();
   ...
};

So, my question: Does anyone have a real-world example where covariant return types of virtual functions are required, or produce a superior solution to simply returning a base pointer or reference?

Answer

Martin v. Löwis picture Martin v. Löwis · Aug 11, 2009

The canonical example is a .clone()/.copy() method. So you can always do

 obj = obj->copy();

regardless what obj's type is.

Edit: This clone method would be defined in the Object base class (as it actually is in Java). So if clone wasn't covariant, you would either have to cast, or would be restricted to methods of the root base class (which would have only very few methods, compared the class of the source object of the copy).