多态性不能与相同数据类型的函数返回值(基本和继承类) [英] Polymorphism is not working with function return values of same data type (Base and Inherited class)

查看:130
本文介绍了多态性不能与相同数据类型的函数返回值(基本和继承类)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在继承的类中重写虚函数,函数应该具有与基类函数相同的返回值的数据类型。

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到派生的类的对象,因此 ID()函数派生 class not Base 类,但在这种情况下,我有 ID() $ c> Base class?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆