【发布时间】:2012-06-01 08:09:19
【问题描述】:
我遇到了一个让我觉得很愚蠢的问题。在一个爱好项目中,我有一个指向接口类的指针的 std::list,它指向所述接口的各种具体实现。
例如,假设我有以下内容:
class Seafood ...
class Fishstick : public Seafood ...
class Squid : public Seafood ...
...
std::list<Seafood*> buffet;
现在我的自助餐里摆满了不同的海鲜,我想数一数我有多少鱼条,看看是否需要从厨房订购更多。
如果没有 RTTI 或其一些迂回的实现,我将如何做到这一点?我读过一些文章声称如果您发现自己想要使用 RTTI,那么您正在以错误的方式接近 OOP 和/或您的解决方案应该重新设计。是否有一些模式或其他解决方案可以解决这个问题?我敢肯定之前已经出现过很多次了。
我在想很明显这是某种虚函数,但如果不构建一个俗气的 RTTI 版本,或者对接口中的后代的一些知识(CountIfFishstick / IsFishstick / Is),我无法弄清楚如何做到这一点(类型))。
edit:想到的另一件事是保留一份fishsticks 列表、一份squid 列表等。但这肯定会破坏接口/实现的整个目的。
【问题讨论】:
-
正如你所说,这里有一点代码味道:要么你关心特定类型(你似乎关心),要么你不关心(使用接口)。请注意,多态性不是能够将它们一起存储在容器中,而是能够通过固定接口使用派生类型(例如在调用函数时),因此您可能希望将它们分开(出于计数目的)和尚未使用界面或其他用途。
-
如果您绝对必须检查变量的类型以确定其性质,
bool isFishstick = !!dynamic_cast<Fishstick *>(value);应该可以工作。也就是说,您应该寻找解决此问题的其他方法。 -
害怕RTTI之类的东西其实很傻。有气味并不表示设计不良,它表明可能存在不良设计。虽然多态性是关于同等对待事物,但有时有必要(例如在计算具体类型时)深入研究继承的更高层次。这样做而不是其他一些令人费解的事情通常是最简单和最好的方法。
标签: c++ oop design-patterns polymorphism