【发布时间】:2011-03-04 12:00:53
【问题描述】:
(这个问题应该可以参考 Stroustrup 来回答。)
能够请求指向最派生类的指针似乎非常有用,如下所示:
class Base { ... };
class DerivedA { ... };
class DerivedB { ... };
class Processor
{
public:
void Do(Base* b) {...}
void Do(DerivedA* d) {...}
void Do(DerivedB* d) {...}
};
list<Base*> things;
Processor p;
for(list<Base*>::iterator i=things.begin(), e=things.end(); i!=e; ++i)
{
p.Do(CAST_TO_MOST_DERIVED_CLASS(*i));
}
但是 c++ 中没有提供这种机制。为什么?
更新,激励示例:
假设您没有 Base、Derived 和 Processor,而是:
class Fruit
class Apple : public Fruit
class Orange: public Fruit
class Eater
{
void Eat(Fruit* f) { ... }
void Eat(Apple* f) { Wash(f); ... }
void Eat(Orange* f) { Peel(f); ... }
};
Eater me;
for each Fruit* f in Fruits
me.Eat(f);
但这在 C++ 中很难做到,需要像访问者模式这样的创造性解决方案。那么问题来了:为什么在 C++ 中这样做会很棘手,而像“CAST_TO_MOST_DERIVED”这样的东西会让它变得更简单?
更新:维基百科无所不知
我认为 Pontus Gagge 有一个很好的答案。从Multiple Dispatch 上的维基百科条目中添加这一点:
“Stroustrup 提到他喜欢The Design and Evolution of C++ 中的Multi-methods 概念,并考虑在C++ 中实现它,但声称无法找到有效的示例实现(与虚函数)并解决一些可能的类型歧义问题。他接着说,虽然这个特性仍然很好,但它可以使用双重分派或 C/C++ 示例中概述的基于类型的查找表来近似实现以上是未来语言修订的低优先级功能。”
作为背景,您可以阅读关于Multi-Methods 的简短摘要,这比我提到的那种电话要好,因为它们会起作用。
【问题讨论】:
-
我以前见过一些破解设计,但是......哦,伙计......
Base::Do(),DerivedA::Do(),DerivedB::Do(),问题就消失了。 -
但有时这不是一个选项,或者在语义上它不是最佳选择。请参阅下面对 DeadMG 的回复。
标签: c++ inheritance rtti multiple-dispatch dynamic-dispatch