c++ - 多态性和引用切片

标签 c++ polymorphism multiple-dispatch single-dispatch

我没有完全理解 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);
}

output : Don't want to operate that low spaceship!

最佳答案

这里没有切片。

C++ 使用单分派(dispatch)而不是多分派(dispatch)。

virtual 完成的分派(dispatch)仅通过 this 实例完成。

所以在

pilot.operate(ship);

只有 pilot 的调度(并且使用动态类型的 pilot),但是我们使用静态类型的 ship(所以 SpaceShip& )

您必须使用访问者或自己实现多重分派(dispatch)。

例如:

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);
}

Demo

关于c++ - 多态性和引用切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33894741/

相关文章:

function - 在 Julia v0.5+ 中调度函数

types - 可以在 OCaml 中的类型之间编码二进制函数吗?

c++ - 将点云的坐标转换为点云库中的另一个坐标,使地平面成为X-O-Y平面?

c++ - 如何访问 `polymorphic` 的任何子级的 `std::variant` 基类?

c++ - 从代码内部编译 QT 源代码

mongodb - 去 + MongoDB : polymorphic queries

c++ - 继承和多态性——易用性与纯粹性

raku - 当使用 nextsame 或 callame 时,奇怪的 "Can' t use unknown trait

C++ 成员函数作为友元

c++ - 错误 : '_mm512_loadu_epi64' was not declared in this scope