Override a Member Function with Different Return Type

Override a member function with different return type

Overriding essentially 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 the Standard enforces this condition.

If the above condition was not in place it would leave a window to break the existing code by addition of new functionality.

function overriding with different return types

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).

C++ Overriding virtual function with different return type

In fact, this method:

virtual tErrorCode CheckThis(int id, char something);

Does not override anything, because it has a different signature from this method:

virtual bool CheckThis(int id);

Note, that you might use the override specifier to ensure that the method in the derived class actually overrides the method of the base class.

So, this piece of code:

class Foo {
protected:
virtual bool CheckThis(int id);
};

class Bar : public Foo
{
protected:
virtual tErrorCode CheckThis(int id, char something) override;
};

Will not compile, but this one will:

class Foo {
protected:
virtual bool CheckThis(int id);
};

class Bar : public Foo
{
protected:
virtual bool CheckThis(int id) override;
};

Can overridden methods differ in return type?

Java supports* covariant return types for overridden methods. This means an overridden method may have a more specific return type. That is, as long as the new return type is assignable to the return type of the method you are overriding, it's allowed.

For example:

class ShapeBuilder {
...
public Shape build() {
....
}

class CircleBuilder extends ShapeBuilder{
...
@Override
public Circle build() {
....
}

This is specified in section 8.4.5 of the Java Language Specification:

Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.

A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:

  • If R1 is void then R2 is void.

  • If R1 is a primitive type, then R2 is identical to R1.

  • If R1 is a reference type then:

    • R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or

    • R1 = |R2|

("|R2|" refers to the erasure of R2, as defined in §4.6 of the JLS.)


* Prior to Java 5, Java had invariant return types, which meant the return type of a method override needed to exactly match the method being overridden.

Override method with different return type in c++

Yes, C++ does support covariant return types with raw pointers. So the following is possible:

class ProgramNodeBase
{
public:
virtual FunctionBase* GetEdgeFunction(unsigned int position);
};

class ProgramNode : public ProgramNodeBase
{
public:
Function* GetEdgeFunction(unsigned int position) override;
};

For this to work, the definition of Function must be available where the overrider is declared—the compiler must be able to verify that the return type is actually covariant.

Of course, you will have to provide an appropriate implementation for the overrider.

Override virtual function with different return type

Static type checking must still hold, even if the dynamic type does something slightly different in the implementation. So it really depends on the static type of the object being pointed at. When you call the virtual member on an A*, the return type is specified as A*.

If you were to call it on a B*, the return type of the function would have been (statically) a B*.

B *obj = new B();
obj->func();
B *obj2 = obj->func(); // Okay now

Whenever you deal with run-time polynorphism in C++, it's the static type of the objects that determines the interface.

Why using a different return type in virtual function declaration throws an error instead of resulting in a redefinition?

When the compiler encounters the matching signature (arguments, constness), it automatically makes the void f() const declaration virtual. So the definition of Derived is interpreted as:

class Derived: public Base
{
public:
virtual void f() const {} // virtual keyword is added
};

It clearly looks like an attempt to override Base::f(). All this happens because the function signatures match in the Base and Derived class. If the signatures didn't match, then only would this be a redefinition in which case it would've hidden the Base::f() in Derived class.

Overriding a base class function with different return types

You can't overload by return type. I think that a template would work better in your case. There's no need for polymorphism or inheritance here:

template<class T>
class Variable {
protected:
T value;
std::string name;
public:
Variable(std::string n, T v);
Variable (const Variable& other);
virtual ~Variable(){};
T getVal();
};

The usage would be pretty simple:

Variable<bool> condition("Name", true);
Variable<char> character("Name2", 'T');
Variable<unsigned> integer("Name3", 123);
std::cout << condition.getVal() << '\n';
std::cout << character.getVal() << '\n';
std::cout << integer.getVal() << '\n';


Related Topics



Leave a reply



Submit