C++ 多重分派(dispatch)

标签 c++ inheritance polymorphism multiple-dispatch

给定以下问题:

class Instrument {
};

class Guitar : public Instrument {
  public:
    void doGuitar() const;
};

class Piano : public Instrument {
  public:
    void doPiano() const;
};

我得到了指向 Instrument 的指针列表

list<shared_ptr<Instrument>> instruments;

在其中我通过(例如)添加乐器

Guitar myGuitar;
instruments.push_back(make_shared<Guitar>(myGuitar));

现在,我想遍历列表 instruments 并调用 doPiano() 当且仅当当前乐器是钢琴和 doGuitar()如果它是一把吉他。这两个函数差别很大,因此不能在 Instrument 类中进行抽象。

问题是 C++ 无法通过运行时识别 Instrument 的类型,不是吗(由于单次分派(dispatch))?我怎样才能实现它根据迭代器指向的当前类型调用钢琴或吉他功能。

如果我能实现某事,我会很高兴。像这样伪代码工作:

list<shared_ptr<Instrument>>::const_iterator it;
if ("current type == Guitar")
  (*it)->doGuitar();
else if ("current type == Piano")
  (*it)->doPiano();

结果

实际上,我的方法遇到了几个问题。我使用这篇文章做了很多重构:How does one downcast a std::shared_ptr? .感谢大家的帮助:)

最佳答案

可能可以改进设计以消除此问题,但在现有设计中,您可以添加一个虚拟成员函数 Instrument::play_itPlayer 作为多态参数。在Player中有两个函数play_guitar(以吉他为参数)和play_piano(以钢琴为参数)。在吉他类中重写 play_it 以调用 Player::play_guitar 并将 self 作为参数。在 piano 类中重写 play_it 以调用 Player::play_piano 并将 self 作为参数。看起来没有石膏。

这不完全是多重分派(dispatch),它被称为访问者模式。然而,最好不要过分关注这一点,以免您开始为事物命名 visitor 或此类非描述性的愚蠢行为。

关于C++ 多重分派(dispatch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41097609/

相关文章:

c++ - "pure virtual function call"崩溃从何而来?

c++ - 同步程序与更新的输入文件

c++ - C++ 中的 C# Dll,如何

c++ - automake undefined reference

python - 继承方法的正确方法 1 更正

c++ - C++ 中的静态多态性

c++ - 为什么在 C++ 中进行强制转换会打印出意想不到的结果?

javascript - 使用自定义按钮扩展 L.control.zoom

c# - 如何正确连接现有的密封类?

C++ 让两个子类共享其基类中的一个变量