简体   繁体   English

使用相同的参数和不同的返回类型重载虚拟函数

[英]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. 我想函数foo()在派生类Son被重写,并且没有重载,因为以下程序给了我错误。

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. 但是,当我在第一个程序中将函数foo()声明为virtual函数时,出现错误,并且无法理解原因。 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 . 除了在Father类中将函数foo()声明为virtual ,我没有做任何更改。 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). 您不能通过更改返回类型,仅通过更改函数的参数类型/数量(或添加const修饰符,以及可能的其他几种方式)来重载。 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. 然后将调用Father::foo() ,如果Father::foo()不是虚拟的,则不会调用Son::foo()

Since Son::foo() isn't overriding Father::foo() , there is no special requirement that the return types match. 由于Son::foo()没有覆盖Father::foo() ,因此没有特殊要求返回类型必须匹配。 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. 但是,一旦将Father::foo()虚拟化,则Son::foo()会覆盖Father::foo() ,因此返回类型需要达成协议。

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 . 例如,可以在此处找到参考。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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