C ++ virtual function return type

Is it possible for an inherited class to implement a virtual function with a different return type (without using a template as a return)?

+59
c ++ override inheritance return-type virtual-functions
Jan 12 2018-11-11T00:
source share
3 answers

In some cases, yes, it is legal for a derived class to override a virtual function using a different return type if the return type is covariant with the original return type. For example, consider the following:

class Base { public: virtual ~Base() {} virtual Base* clone() const = 0; }; class Derived: public Base { public: virtual Derived* clone() const { return new Derived(*this); } }; 

Here Base defines a pure virtual function called clone , which returns Base * . In a derived implementation, this virtual function is overridden using the Derived * return type. Although the return type does not match the base, it is absolutely safe, because at any time you write

 Base* ptr = /* ... */ Base* clone = ptr->clone(); 

Calling clone() will always return a pointer to a Base object, because even if it returns Derived* , this pointer is implicitly converted to Base* , and the operation is correctly defined.

In general, the return type of a function is never considered part of its signature. You can override a member function with any return type if the return type is covariant.

+64
Jan 12 '11 at 3:45
source share

Yes. The types of returned data may be different if they are covariant . The C ++ standard describes this as follows (Β§10.3 / 5):

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

  • both are pointers to classes or class references 98)
  • the class of the return type B::f is the same class as the class of the return type D::f or, is the unambiguous direct or indirect base class of the class in the return type D::f and is available in D
  • both pointers or references have the same cv qualification, and the class type in the return type D::f has the same cv qualification as or less cv-qualification than the class type in the return type B::f .

Footnote 98 indicates that "multilevel pointers to classes or references to multilevel pointers to classes are not permitted."

In short, if D is a subtype of B , then the return type of the function in D must be a subtype of the return type of the function in B The most common example is when return types themselves are based on D and B , but they do not have to be. Consider this where we have two separate type hierarchies:

 struct Base { /* ... */ }; struct Derived: public Base { /* ... */ }; struct B { virtual Base* func() { return new Base; } virtual ~B() { } }; struct D: public B { Derived* func() { return new Derived; } }; int main() { B* b = new D; Base* base = b->func(); delete base; delete b; } 

The reason for this is that any func caller expects a Base pointer. Any Base pointer will do. So, if D::func promises always returns a Derived pointer, then it will always satisfy the contract set by the ancestor class, because any Derived pointer can be implicitly converted to a Base pointer. This way, subscribers will always get what they expect.




In addition to the fact that the type of the return value may vary, some languages ​​also allow you to change the types of parameters of the override function. When they do this, they usually have to be contravariant. That is, if B::f accepts a Derived* , then D::f will be allowed to accept Base* . Descendants are allowed to be free in what they will accept, and more strict in what they return. C ++ does not allow contravariance of the parametric type. If you change the types of parameters, C ++ considers this a completely new function, so you start to overload and hide. For more on this topic, see Covariance and contravariance (computer science) on Wikipedia.

+44
Jan 12
source share

An implementation of a virtual function of a derived class may have a covariant return type .

+2
Jan 12 '11 at 3:45
source share



All Articles