【问题标题】:Polymorphism and Slicing with references多态性和切片与引用
【发布时间】:2015-11-24 13:17:17
【问题描述】:

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

输出:不想操作那艘低矮的飞船!

【问题讨论】:

  • 注意:在 Jarod 花时间回答您的《星球大战》示例以将其更改为动物/英雄之后,这并不是那么酷。该站点希望后代提供问题和答案(这样它们不仅可以帮助您,还可以帮助未来的人),因此将您的示例源代码从星球大战更改为类似 RPG NPC 示例有点令人困惑。我的建议是保持它原来的样子,除非你真的必须把它改成别的东西。
  • @Ike 没有看到答案,我认为更改它是安全的。我回来时会变回来
  • 干杯——如果你想加入那种动物/英雄的战斗例子,你可以编辑它并将它添加到星球大战下面。但是,如果可以的话,请尽量避免将您的问题与答案脱节,以免给未来的读者造成混淆。

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


【解决方案1】:

这里没有切片。

C++ 使用单一调度而不是多重调度。

virtual 完成的调度仅对 this 实例完成。

这样

pilot.operate(ship);

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

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

例如:

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

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 2019-10-28
    • 2018-07-29
    • 2018-08-20
    • 2021-12-31
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多