![](/img/trans.png)
[英]pure virtual functions overloading and covariant return types with multiple inheritance
[英]Overloading Virtual Functions with same arguments and different return types
我有以下代码,编译时没有任何错误或警告。
#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;
}
输出如下所示。
long foo
n is 222
我想函数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;
}
错误消息如下所示。
error: 'long int Father::foo()' cannot be overloaded
error: with 'int Father::foo()'
两种结果都符合预期,因为当两个函数的区别仅在于返回类型时,则发生覆盖而不是重载。 但是,当我在第一个程序中将函数foo()
声明为virtual
函数时,出现错误,并且无法理解原因。 我违反了什么规则? 该程序如下所示,
#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;
}
错误消息如下所示,
error: conflicting return type specified for 'virtual long int Son::foo()'
error: overriding 'virtual int Father::foo()'
除了在Father
类中将函数foo()
声明为virtual
,我没有做任何更改。 然后突然出现了第一个程序中没有的冲突。 我无法理解这一点。
有什么建议么? 谢谢。
您不能通过更改返回类型,仅通过更改函数的参数类型/数量(或添加const修饰符,以及可能的其他几种方式)来重载。 在派生类中进行编译时会编译的原因是,派生类本质上是从基类中隐藏了一个。
请参考返回类型的函数重载? 关于为什么基于返回类型的重载/重载会成为问题。
当成员函数不是虚函数时,在派生类中具有相同名称的函数不会覆盖基类中的函数,至少在通常情况下不会如此。 派生类函数仅隐藏基类函数。 例如,如果您有如下代码:
Son s;
Father &f = s;
f.foo();
然后将调用Father::foo()
,如果Father::foo()
不是虚拟的,则不会调用Son::foo()
。
由于Son::foo()
没有覆盖Father::foo()
,因此没有特殊要求返回类型必须匹配。 但是,一旦将Father::foo()
虚拟化,则Son::foo()
会覆盖Father::foo()
,因此返回类型需要达成协议。
此外,当您具有不同的参数类型而不是不同的返回类型时,就会发生重载。 在同一个作用域中声明两个具有相同名称而仅在返回类型上有所不同的函数是完全非法的。
虚假函数的返回提示与基类不同,派生函数的返回函数从标准允许,并称为协变函数。
但是,某些约束适用于返回类型。 基本上,如果它返回一个指向类的指针或引用,则可以定义一个协变函数。 在这种情况下,基类必须返回由其子级返回的指向该类的直接或间接祖先的指针或引用。
例如,可以在此处找到参考。
第一个示例程序采用了覆盖的概念,因此将调用派生类中定义的函数。在虚拟示例程序中,如果在基类中将某个函数声明为虚函数,则需要在派生类中使用该函数具有与基类虚函数相同的签名。在这种情况下,派生类中的函数类型有所不同,因此会产生错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.