【发布时间】:2016-12-12 09:23:09
【问题描述】:
鉴于以下问题:
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 的类型,不是吗(由于单次调度)?根据迭代器指向的当前类型,如何实现它调用钢琴或吉他功能。
如果我能实现某事,我会很高兴。像这样的伪代码工作:
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?。感谢大家的帮助:)
【问题讨论】:
-
为什么不简单地使用一个虚拟的
do函数来做正确的事情? -
看看
std::dynamic_pointer_cast。然后撕掉你的设计并重新开始。多态性只适用于所有派生类可以合理共享同一个接口的情况。 -
其实,我的例子只是我“真实”实现的一小部分。
Instrument中有几个纯虚函数。我应该提到它。 -
既然你提到了多次调度,你可能想看看visitor pattern。
-
"这两个函数差别很大,因此不能在 Instrument 类中抽象化。"显示真实代码。就目前而言,do_piano 和 do_guitar 完全一样,应该在 Instrument 中作为一个通用的纯虚函数。你需要一个令人信服的相反论据。
标签: c++ inheritance polymorphism multiple-dispatch