【发布时间】:2015-03-21 03:50:21
【问题描述】:
据我所知,要在继承类中覆盖虚函数,该函数应该具有与基类函数相同的返回值数据类型。
但是如果你返回一个指针或值,它属于从原始函数的返回值的类继承的类,编译器将接受更改返回值,如下所示:
#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
Derived 类中重写的 clone() 函数返回指向堆上相同对象副本的指针。从输出中可以看出,每次都会调用正确版本的clone(),但不会调用ID()。为了解决这个问题,我不得不通过dynamic_cast 或在基类中制作virtual ID() 来降低返回值以获得所需的效果。
我的问题:为什么多态性在第一种情况下不起作用
std::cout << bp->clone()->ID() <<"\n";
因为clone() 应该从Derived 类返回一个指向对象的指针,因此Derived 类的ID() 函数不是Base 类,但在这种情况下我有@ 的ID() 函数987654336@班级?
【问题讨论】:
-
您是否忘记了 Base::ID 前面的
virtual?目前它不是一个多态函数。 -
不,正如我在问题中所说,我已经测试了这个选项。其实我本来打算不使用 virtual 关键字来测试 ID() 的输出。
-
但是你的问题是为什么多态性在没有的情况下不起作用。原因是ID函数不是虚拟的。
-
如果你说它的类型是
Base,编译器应该如何知道bp是否是Derived?显然,一切都很清楚,因为您调用clone就好像它是基类的方法一样。 -
我的问题是 clone() 将返回 Derived* 指针,所以当我调用 clone()->ID 为什么返回值被视为 Base* 指针。那么我为什么要使用 virtual 呢?
标签: c++ inheritance polymorphism