简体   繁体   中英

Overloading Virtual Functions with same arguments and different return types

I have the following code which compiled without any error or warning.

#include<iostream>

using namespace std;

class Father
{
   public:
   int foo()
   {
       cout<<"int foo";
       return 111;
   }
};
class Son: public Father
{
   public:
   long foo()
   {
       cout<<"long foo";
       return 222;
   }
};

int main()
{
  Son x;
  long n;
  n=x.foo();
  cout<<"\nn is "<<n;
  return 0;
}

The Output is shown below.

long foo
n is 222

I suppose the function foo() was overridden in the derived class Son and not overloaded as the following program gave me errors.

using namespace std;

class Father
{
   public:
   int foo()
   {
       cout<<"int foo";
       return 111;
   }
   long foo()
   {
       cout<<"long foo";
       return 222;
   }
};


int main()
{
  Father x;
  long n;
  n=x.foo();
  cout<<"\nn is "<<n;
}

The error message is shown below.

error: 'long int Father::foo()' cannot be overloaded
error: with 'int Father::foo()'

Both the outcomes where expected, because when two functions differ only by the return type then overriding takes place instead of overloading. But when I declared the function foo() as virtual in the first program, I am getting errors and I am unable to understand the reason. What rule did I violate? The program is shown below,

#include<iostream>

using namespace std;

class Father
{
   public:
   virtual int foo()
   {
       cout<<"int foo";
       return 111;
   }
};
class Son: public Father
{
   public:
   long foo()
   {
       cout<<"long foo";
       return 222;
   }
};


int main()
{
  Son x;
  long n;
  n=x.foo();
  cout<<"\nn is "<<n;
}

The error message is shown below,

error: conflicting return type specified for 'virtual long int Son::foo()'
error:   overriding 'virtual int Father::foo()'

I haven't made any change other than declaring function foo() as virtual in class Father . Then suddenly there arises a conflict which was absent in the first program. I am unable to comprehend this.

Any Suggestions? Thank you.

You can't overload by changing the return type, only by changing the types/number of arguments to the function (or adding a const modifier, and possibly a few other ways). The reason it compiles when you do it in the derived class is because the derived one essentially hides the one from the base class.

Please refer to Function overloading by return type? regarding to why return type based overloading/overriding can be problematic.

When a member function is not virtual, a function with the same name in the derived class doesn't override the function in the base class, at least not in the usual sense. The derived class function merely hides the base class function. For example, if you had code like this:

Son s;
Father &f = s;
f.foo();

Then it is Father::foo() that would be called, not Son::foo() if Father::foo() is not virtual.

Since Son::foo() isn't overriding Father::foo() , there is no special requirement that the return types match. Once you make Father::foo() virtual however, then Son::foo() does override Father::foo() , and so there needs to be an agreement in the return type.

Moreover, overloading occurs when you have different argument types, not different return types. It is simply illegal to have two functions with the same name declared in the same scope that only differ by their return type.

Virtual functions whose return tipe differ from the base classes and the derived ones are allowed from the standard and are named covariant functions.

Some constraints, however, apply to the return types. Basically you are allowed to define a covariant function if it returns a pointer or a reference to a class; in this case the base class must return a pointer or a reference to a direct or indirect ancestor of the class which is returned by its sons.

References can be found, for example, here .

第一个示例程序采用了覆盖的概念,因此将调用派生类中定义的函数。在虚拟示例程序中,如果在基类中将某个函数声明为虚函数,则需要在派生类中使用该函数具有与基类虚函数相同的签名。在这种情况下,派生类中的函数类型有所不同,因此会产生错误。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM