多态性不适用于相同数据类型(基类和继承类)的函数返回值

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()
" ;
    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.

这篇关于多态性不适用于相同数据类型(基类和继承类)的函数返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:多态性不适用于相同数据类型(基类和继承类)的函数返回值

基础教程推荐