32

Consider the example below:

#include <iostream>

using namespace std;

class base
{
   public:
      virtual int func()
      {
         cout << "vfunc in base class\n";
         return 0;
      }
};

class derived: public base
{
   public:
      double func()
      {
         cout << "vfunc in derived class\n";
         return 0;
      }
};

int main()
{
   base *bptr = new derived;
   bptr->func();

   return 0;
}

The compiler gives an error for the above code that there is conflicting type for the overriden function. Why is it not possible to override a function in the derived class with a different return type ?

I believe, in-order to override a function, the base class virtual method needs to be redefined in the derived class. To redefine a method, the signatures of the methods has to be the same. Since return type is not part of the signature, i believe even if there is difference in return type, the method will still be redefined? In that case for the code above, virtual function func is redefined in the derived class with a different return type. But the compiler throws an error. Is my understanding correct?

4
  • 1
    For clarification's sake, what compiler is giving you what error? Commented Jan 23, 2012 at 4:54
  • @SionSheevok, GCC does at least: codepad.org/z7rXpCeK
    – bdonlan
    Commented Jan 23, 2012 at 4:54
  • @SionSheevok :I am using gcc 3.4.6 Commented Jan 23, 2012 at 4:55
  • Nod I wasn't suggesting it doesn't give an error, but merely curious what the compiler was specifically trying to communicate. Commented Jan 23, 2012 at 4:56

5 Answers 5

38

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.

1
  • 7
    Als: type derived from that(co-variant return types). That was critical for my understanding. Nice explanation. :) Commented Jan 23, 2012 at 5:12
16

In order to override a virtual function, the return value must be exactly the same*. C++ will not automatically convert between double and int here - after all, how would it know what return type you want when calling from a derived class pointer? Note that if you change part of the signature (parameters, const-ness, etc), then you can change the return value as well.

* - strictly speaking, it must be 'covariant'. What this means is that the type you return must be a subset of the parent function's return type. For example, if the parent class returns a base *, you could return a derived *. Since deriveds are simultaneously also bases, the compiler lets you override in this manner. But you can't return totally unrelated types such as int and double; just because there's an implicit conversion doesn't mean the compiler will let you do this kind of override.

6
  • Note that if you change part of the signature (parameters, const-ness, etc), then you can change the return value as well. If i do that then the function is not overriden right? Commented Jan 23, 2012 at 4:57
  • 3
    Exactly the same or a subclass, I think you mean.
    – Nemo
    Commented Jan 23, 2012 at 4:58
  • 1
    co-variant return types are allowed for virtual functions.
    – Alok Save
    Commented Jan 23, 2012 at 4:59
  • @LinuxPenseur, correct, the function won't be overriden if the signature changes
    – bdonlan
    Commented Jan 23, 2012 at 5:05
  • @Als: For emphasis, may we offer you our chic italics, and this just in, bold face?
    – Kerrek SB
    Commented Jan 23, 2012 at 5:06
10

See this question. To summarize, you can only override a virtual function using a different return type if the types are covariant.

2
  • The types aren't covariant, the override is.
    – Kerrek SB
    Commented Jan 23, 2012 at 5:00
  • No, only your interpretation of it is a bit idiosyncratic.
    – Kerrek SB
    Commented Jan 23, 2012 at 5:03
2

If you want to override, you should try to use template.

See the following:

#include <iostream>

using namespace std;

class base
{
   public:
      template<typename X> X func()
      {
         cout << "vfunc in base class\n";
         return static_cast<X>(0);
      }  
};    

class derived: public base
{
   public:
      template<typename X> X func()
      {
         cout << "vfunc in derived class\n";
         return static_cast<X>(2);
      }  
};    

int main()
{
   derived *bptr = new derived;
   cout << bptr->func<int>() << endl;
   cout << dynamic_cast<base*>(bptr)->func<int>() << endl;

   derived *bptr2 = new derived;
   cout << bptr->func<double>() << endl;
   cout << dynamic_cast<base*>(bptr)->func<int>() << endl;


   return 0;
}

Of course, you dont need to declare it on two different class that way, you could do:

class base
{
   public:
      int func()
      {
         cout << "vfunc in base class\n";
         return 0;
      }  

      double func(){
        cout << "vfunc for double class\n";
        return 2.;

      }
};
-2

Overriding is not posssible ,as the signatures are same and the only difference is the return value. The basic purpose of overriding is polymorphism but it is not possible in the above example

3
  • 2
    The signatures are same here. The functions differ only in return type and return type is not part of the signature. Commented Jan 23, 2012 at 5:04
  • 1
    @LinuxPenseur thanks for telling , that is what I intended to mean
    – kvk
    Commented Jan 23, 2012 at 5:21
  • When overriding a method it is possible to change the return type as long as this change does not conflict (the type is covariant) with the declared method. This does not break the polymorphism as the covariant type of the override is also valid type for the method declaration.
    – djabi
    Commented Feb 24, 2021 at 21:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.