问题描述
据我所知,要在继承类中覆盖虚函数,该函数应该具有与基类函数相同的返回值数据类型.
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()
" ;
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()
" ;
Derived * dp = new Derived ;
return dp ;
}
std::string ID() {return "Derived class";}
};
int main() {
Base * bp = new Derived;
std::cout << bp->clone()->ID() <<"
";
std::cout << dynamic_cast <Derived*>(bp->clone())->ID() <<"
";
/*
next code give error: cannot convert Base* to Derived*:
Derived * dp2 = bp->clone();
std::cout << dp2->ID() << "
";
*/
}
g++ 的输出是:
Derived::clone()
Base class
Derived::clone()
Derived class
Derived
类中的
重写clone()
函数返回指向堆上同一对象的副本的指针.从输出中可以看出,每次都会调用正确版本的 clone()
,但不会调用 ID()
.为了解决这个问题,我必须通过 dynamic_cast
或在基类中制作 virtual 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() <<"
";
as clone()
应该从 Derived
类返回一个指向 Object 的指针,因此 Derived 的
类不是 ID()
函数Base
类,但在这种情况下,我有 Base
类的 ID()
函数?
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 ?
推荐答案
多态在这种情况下工作正常.当您期望 Derived class
时代码打印 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 *
,因此编译器会看到 <代码>基础*代码>.当编译器稍后在代码中看到 bp->clone()
时,它知道 Base
类的 clone()
方法返回一个 <代码>基础*代码>.最后,当编译器到达 ->ID()
方法调用时,它会查看 Base
类定义并看到一个 non-virtual 方法所以它确保在运行时,在该位置调用 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
关键字.您还可以在 Derived::ID()
override 关键字> 如果您使用符合 C++2011 的编译器.
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.
这篇关于多态性不适用于相同数据类型(基类和继承类)的函数返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!