据我所知,要重写继承类中的虚函数,该函数的返回值数据类型应与基类函数相同。
但是,如果您返回的指针或值属于从原始函数的返回值的类继承的类,则编译器将接受更改返回值,如下所示:
#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()
函数于Derived
类返回一个指向堆上同一对象的副本的指针。从输出中可以看出,正确的版本clone()
每次都会被调用但不是ID()
。为了解决这个问题,我不得不向下转换返回值以获得所需的效果dynamic_cast
或使virtual ID()
在基类中。
我的问题:为什么多态性在第一种情况下不起作用
std::cout << bp->clone()->ID() <<"\n";
as clone()
应该返回一个指向对象的指针Derived
类,因此ID()
的函数Derived
类不Base
类,但在这种情况下我有ID()
的功能Base
class ?
在这种情况下,多态性可以正常工作。打印代码的原因Base class
当你期待的时候Derived class
是因为ID()
方法不是virtual
.
为了了解发生了什么,您必须像编译器一样查看代码。在你的例子中,bp
是一个指向 a 的指针Derived
实例,但它已被键入为Base *
在代码中,这样编译器就会看到Base *
。当编译器稍后在代码中看到bp->clone()
它知道clone()
的方法Base
类返回一个Base *
。最后当编译器到达->ID()
方法调用,它会查看Base
类定义并看到非虚拟的方法,因此它确保在运行时,Base::ID()
方法在该位置被调用。
如果您想具有多态行为,请添加virtual
两个 ID() 方法的关键字。您还可以添加override https://stackoverflow.com/a/11609941/197371关键字Derived::ID()
如果您使用 C++2011 兼容的编译器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)