多态性不能与相同数据类型的函数返回值(基本和继承类) [英] Polymorphism is not working with function return values of same data type (Base and Inherited class)
问题描述
据我所知,在继承的类中重写虚函数,函数应该具有与基类函数相同的返回值的数据类型。
As far as I know to override virtual function in the inherited class the function should have the same data type of the return value as the base class function.
但是,如果您返回一个指针或值,它属于从原始函数的返回值的类继承的类,则编译器将接受更改返回值,如下所示:
But the compiler will accept changing the return value if you return a pointer or value which belong to a class inherited from the class of the return value of the original function as following:
#include <iostream>
class Base{
public:
virtual Base * clone() {
std::cout << "Base::clone()\n" ;
Base * bp = new Base ;
return bp ;
}
std::string ID() {return "Base class";}
};
class Derived: public Base {
public:
//Derived* and Base* are same data type (acceptable):
Derived * clone() {
std::cout << "Derived::clone()\n" ;
Derived * dp = new Derived ;
return dp ;
}
std::string ID() {return "Derived class";}
};
int main() {
Base * bp = new Derived;
std::cout << bp->clone()->ID() <<"\n";
std::cout << dynamic_cast <Derived*>(bp->clone())->ID() <<"\n";
/*
next code give error: cannot convert Base* to Derived*:
Derived * dp2 = bp->clone();
std::cout << dp2->ID() << "\n";
*/
}
g ++的输出是:
Derived::clone()
Base class
Derived::clone()
Derived class
覆盖 clone c> Derived
类返回一个指向堆上同一对象的副本的指针。从输出中可以看出, clone()
的正确版本每次调用,但不是 ID()
。为了解决这个问题,我不得不通过 dynamic_cast
来下调返回值以获得所需的效果,或者使虚拟ID()
在基类中。
Overriden clone()
function in Derived
class returned a pointer to a copy of the same object on heap. As seen from output the right version of clone()
is called every time but not ID()
. To solve this problem I had to downcast the return value to get the desired effect by dynamic_cast
or to make virtual ID()
in base class.
我的问题:为什么多态性在第一种情况下不起作用
My Question: why polymorphism didn't work in the first case
std::cout << bp->clone()->ID() <<"\n";
作为 clone到
class?派生的
类的对象,因此 ID()
函数派生
class not Base
类,但在这种情况下,我有 ID()
$ c> Base
as clone()
should return a pointer to an Object from Derived
class and consequently the ID()
function of Derived
class not Base
class, but in this case I have ID()
function of the Base
class ?
推荐答案
当你期望派生类
时,代码打印基类
的原因是因为 ID )
方法不是 virtual
。
The polymorphism is working properly in that case. The reason the code is printing Base class
when you expect Derived class
is because the ID()
method is not virtual
.
为了理解会发生什么,看看代码就好像你是编译器。在你的示例中, bp
是指向 Derived
实例的指针,但它已被键入 Base *
,因此编译器看到一个 Base *
。当编译器稍后在代码中看到 bp-> clone()
时,它知道 clone()
Base
类返回 Base *
。最后,当编译器到达 - > ID()
方法调用时,它查看 Base
一个非虚拟方法,以确保在运行时, Base :: ID()
方法在该位置被调用。
In order to understand what happens, you have to look at the code as if you were the compiler. In your example, bp
is a pointer to a Derived
instance but it has been typed as Base *
in the code so the compiler sees a Base *
. When the compiler later in code sees bp->clone()
it knows that the clone()
method of the Base
class returns a Base *
. Finally when the compiler reaches the ->ID()
method call, it looks at the Base
class definition and sees a non-virtual method so it ensures that at runtime, the Base::ID()
method is called at that location.
如果您想要具有多态行为,请为两个ID()方法添加 virtual
关键字。您还可以在上添加
。 override
关键字,如果使用符合C ++ 2011的编译器,则派生:: ID()
If you want to have polymorphic behaviour, add virtual
keyword for both ID() methods. You could also add override
keyword on Derived::ID()
if you use a C++2011 compliant compiler.
这篇关于多态性不能与相同数据类型的函数返回值(基本和继承类)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!