YAKOVM
YAKOVM

Reputation: 10153

function overriding with different return types

Does the return type influence on function overriding? (As far as I know return typde is not a part of a function/method signature) In a base class I have a function, which doesn't get arguments, returns int and is pure virtual. In each derived class, I define an enum for the return type.The function is overridden in the derived classes, i.e. it has the same signature but different behavior. The question is: Is that legal for overriding and return type is not a part of function overriding?

Code example:

class Base
{
  public:
  typedef int ret;
  virtual ret method() = 0;
};

class Der1
{
public:
  enum ret1{
    ret1_0,
    ret1_1
  };
  ret1 method() { return ret1_1;}
};

class Der1
{
public:
  enum ret2{
    ret2_0,
    ret2_1
  };
  ret1 method() { return ret2_0;}
};

Upvotes: 5

Views: 6291

Answers (4)

Alok Save
Alok Save

Reputation: 206508

You can override functions with different return types but only covariant return types are allowed.

Function Overriding means that either the Base class method or the Derived class method will be called at run-time depending on the actual object pointed by the pointer.
It implies that:
i.e: Every place where the Base class method can be called can be replaced by call to Derived class method without any change to calling code.

In order to achieve this the only possible way is to restrict the return types of the overriding virtual methods to return the same type as the Base class or a type derived from that(co-variant return types) and so the Standard enforces this condition.

Without this condition the existing code will break by addition of new functionality(new overriding functions).

Upvotes: 5

Arne Mertz
Arne Mertz

Reputation: 24576

Short answer: No, this is not allowed or better put it's not overriding but overwriting, i.e. you are not overriding Base::method() but creating a new method with the same name. Most compilers will warn you about that. With your example code, but assuming that Base::method is not pure virtual, consider this:

void callMethod(Base const& b)
{
  auto a1 = b.method();  //what should the type of a1 be? -> it's int. Every time.
  std::cout << a1 << '\n';
}

int main()
{
  Der1 d1;
  auto a2 = d1.method(); //a2 is ret1_1 of type ret1
  callMethod(d1);        //calls Base::method and prints that int, not Der1::method
}

You are right wrt that return types are not part of the function signature. But when overriding virtual functions, the signature is not all that matters. §10.3,7 explicitly states:

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, both are lvalue references to classes, or both are rvalue 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.

Upvotes: 4

paper.plane
paper.plane

Reputation: 1197

We should not alter the return type of a function in the base class by overriding it. Alteration of the return type by hiding the base member with another is not recommended, because it results into something weird that can't be used in a polymorphic way.

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145204

what you have are not overrides.

c++ supports covariant return types for raw pointers and raw references.

but that's all.

Upvotes: 1

Related Questions