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
What Happens When a Computer Program Runs
Is There a Working C++ Refactoring Tool
.C VS .Cc VS. .Cpp VS .Hpp VS .H VS .Cxx
5 Years Later, Is There Something Better Than the "Fastest Possible C++ Delegates"
Compile a Dll in C/C++, Then Call It from Another Program
How to Create a Function Dynamically, During Runtime in C++
Return a "Null" Object If Search Result Not Found
How to Get the Gl Library/Headers
Fast Fixed Point Pow, Log, Exp and Sqrt
How to Navigate Through a Vector Using Iterators? (C++)
What Are Declarations and Declarators and How Are Their Types Interpreted by the Standard
What Does String::Npos Mean in This Code
Passing as Const and by Reference - Worth It
Profiling the C++ Compilation Process