多态性和与参考文献的切片

Polymorphism and Slicing with references

本文关键字:切片 参考文献 多态性      更新时间:2023-10-16

我没有完全理解C++中的对象切片。在下面的示例代码中,两个对象似乎接受相同的处理,但多态性仅适用于其中一个对象。

我正在使用引用,其中一个对象似乎没有被切片。我相信在launch_ship函数调用过程中一定发生了一些事情,但我不知道到底出了什么问题。

这是示例代码。

#include <iostream>

class SpaceShip
{};
class MilleniumFalcon: public SpaceShip
{};
class Pilot
{
public:
     virtual void operate(SpaceShip&)
    {
        std::cerr << "Operating spaceship" << std::endl;
    }
    virtual void operate(MilleniumFalcon&)
    {
        std::cerr << "Cannot operate that spaceship!" << std::endl;
    }
};
class Chewbacca: public Pilot
{
public:
    virtual void operate(SpaceShip&)
    {
        std::cerr << "Don't want to operate that low spaceship!" <<
                  std::endl;
    }
    virtual void operate(MilleniumFalcon&)
    {
         std::cerr << "Operating the Millenium Falcon" << std::endl;
    }
};
void launch_ship(Pilot& pilot, SpaceShip& ship)
{
      pilot.operate(ship);
}
int main()
{
    Chewbacca chewie;
    MilleniumFalcon millenium;
    launch_ship(chewie, millenium);
}

输出:不想操作那个低飞船!

这里没有切片。

C++使用单个调度,而不是多个调度。

virtual所执行的分派仅针对this实例执行。

所以在中

pilot.operate(ship);

只有pilot(使用动态类型的飞行员)的调度,但我们使用静态类型的ship(因此SpaceShip&

您必须使用访问者或为自己实现多重调度。

例如:

class SpaceShip
{
public:
    virtual void operate_by(Pilot& pilot) { pilot.operate(*this); }
};
class MilleniumFalcon: public SpaceShip
{
public:
    virtual void operate_by(Pilot& pilot) override { pilot.operate(*this); }
};

void launch_ship(Pilot& pilot, SpaceShip& ship)
{
    ship.operate_by(pilot);
}

演示