C++ 覆盖具有不同返回类型的成员函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8967303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Override a member function with different return type
提问by nitin_cherian
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?
我相信,为了覆盖一个函数,基类虚方法需要在派生类中重新定义。要重新定义方法,方法的签名必须相同。由于返回类型不是签名的一部分,我相信即使返回类型存在差异,该方法仍然会被重新定义吗?在上述代码的那种情况下,虚函数func
在派生类中被重新定义为不同的返回类型。但是编译器会抛出错误。我的理解正确吗?
回答by Alok Save
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.
覆盖本质上意味着将根据指针指向的实际对象在运行时调用基类方法或派生类方法。
这意味着:
即:可以调用Base 类方法的每个地方都可以替换为调用Derived 类方法,而无需对调用代码进行任何更改。
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.
为了实现这一点,唯一可能的方法是限制覆盖虚拟方法的返回类型以返回与 Base 类相同的类型或从该类派生的类型(协变返回类型),并且标准强制执行此条件。
If the above condition was not in place it would leave a window to break the existing code by addition of new functionality.
如果上述条件不存在,它将留下一个窗口,通过添加新功能来破坏现有代码。
回答by bdonlan
In order to override a virtual function, the return value must be exactly the same*. C++ will notautomatically 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.
为了覆盖虚函数,返回值必须完全相同*。C++不会在double
和int
这里之间自动转换——毕竟,当从派生类指针调用时,它怎么知道你想要什么返回类型?请注意,如果您更改签名的一部分(参数、常量等),那么您也可以更改返回值。
* - 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 derived
s are simultaneously also base
s, 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.
* - 严格来说,它必须是“协变的”。这意味着您返回的类型必须是父函数返回类型的子集。例如,如果父类返回 a base *
,您可以返回 a derived *
。由于derived
s 同时也是base
s,编译器允许您以这种方式覆盖。但是你不能返回完全不相关的类型,比如int
and double
; 仅仅因为有一个隐式转换并不意味着编译器会让你做这种覆盖。
回答by ezod
See this question. To summarize, you can only override a virtual function using a different return type if the types are covariant.
回答by Werner
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.;
}
};
回答by kvk
Overriding is not posssible ,as the signatures are different. The basic purpose of overriding is polymorphism but it is not possible in the above example
覆盖是不可能的,因为签名是不同的。覆盖的基本目的是多态,但在上面的例子中是不可能的