Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What the C++ rules in regard to covariant return types?

Tags:

c++

Like in the example below, what is allowed, how and why?

class Shape {
      public:
        //...
        virtual Shape *clone() const = 0; // Prototype
        //...
    };
    class Circle : public Shape {
      public:
        Circle *clone() const;
        //...
    };
like image 741
vehomzzz Avatar asked Nov 06 '09 17:11

vehomzzz


People also ask

Which is covariant return type?

Covariant return type refers to return type of an overriding method. It allows to narrow down return type of an overridden method without any need to cast the type or check the return type. Covariant return type works only for non-primitive return types.

What is covariant return type in C++?

In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass. A notable language in which this is a fairly common paradigm is C++. C# supports return type covariance as of version 9.0.

How is covariant return types implemented?

How is Covariant return types implemented? Java doesn't allow the return type-based overloading, but JVM always allows return type-based overloading. JVM uses the full signature of a method for lookup/resolution. Full signature means it includes return type in addition to argument types.

Is covariant return types available in C ++ 17?

C++'s classical OOP system supports “covariant return types,” but it does not support “contravariant parameter types.”


2 Answers

C++ Standard 2003. 10.3.5

The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:

— both are pointers to classes or references to classes

— the class in the return type of B::f is the same class as the class in the return type of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f

— both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.

If the return type of D::f differs from the return type of B::f, the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D. When the overriding function is called as the final overrider of the overridden function, its result is converted to the type returned by the (statically chosen) overridden function (5.2.2).

Example:

class B {};
class D : private B { friend class Derived; };
struct Base {
  virtual B*  vf4();
  virtual B*  vf5();
};
class A;
struct Derived : public Base {
  D* vf4();  // OK: returns pointer to derived class
  A* vf5();  // error: returns pointer to incomplete class
};
like image 53
Alexey Malistov Avatar answered Oct 18 '22 04:10

Alexey Malistov


Pff, too long standard quoting.

You can use another type as covariant if (a) it is a pointer/reference (b) it can be casted to the prior return type by mere addition of a constant known at compilation time (c) it is compliant to all constant-volatile qualifiers.

like image 32
P Shved Avatar answered Oct 18 '22 04:10

P Shved