Reputation: 10153
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
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
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 functionB::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 ofD::f
, or is an unambiguous and accessible direct or indirect base class of the class in the return type ofD::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 ofB::f
.
Upvotes: 4
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
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