我正在尝试用类型类替换简单的枚举......也就是说,从每种类型的基派生一个类。例如,而不是:
enum E_BASE { EB_ALPHA, EB_BRAVO };
E_BASE message = someMessage();
switch (message)
{
case EB_ALPHA: applyAlpha();
case EB_BRAVO: applyBravo();
}
我想做这个:
Base* message = someMessage();
message->apply(this); // use polymorphism to determine what function to call.
我见过很多方法来做到这一点,即使比基本的 switch 语句都显得不太优雅。使用 dyanimc_cast、继承每次添加新消息时都需要更新的 messageHandler 类、使用函数指针容器,所有这些似乎都违背了通过用多态性替换开关来使代码更易于维护的目的。
这是我能得到的最接近的结果:(我使用模板来避免从无所不知的处理程序接口继承)
class Base
{
public:
template<typename T> virtual void apply(T* sandbox) = 0;
};
class Alpha : public Base
{
public:
template<typename T> virtual void apply(T* sandbox)
{
sandbox->applyAlpha();
}
};
class Bravo : public Base
{
public:
template<typename T> virtual void apply(T* sandbox)
{
sandbox->applyBravo();
}
};
class Sandbox
{
public:
void run()
{
Base* alpha = new Alpha;
Base* bravo = new Bravo;
alpha->apply(this);
bravo->apply(this);
delete alpha;
delete bravo;
}
void applyAlpha() {
// cout << "Applying alpha\n";
}
void applyBravo() {
// cout << "Applying bravo\n";
}
};
显然,这不能编译,但我希望它能解决我的问题。
好吧,在屈服于dynamic_cast和多重继承之后,我想出了这个,感谢安东尼·威廉姆斯 http://www.drdobbs.com/cpp/184429055 and 乔齿轮网 http://jogear.net/dynamic-double-dispatch-and-templates#
class HandlerBase
{
public:
virtual ~HandlerBase() {}
};
template<typename T> class Handler : public virtual HandlerBase
{
public:
virtual void process(const T&)=0;
};
class MessageBase
{
public:
virtual void dispatch(HandlerBase* handler) = 0;
template<typename MessageType>
void dynamicDispatch(HandlerBase* handler, MessageType* self)
{
dynamic_cast<Handler<MessageType>&>(*handler).process(*self);
}
};
template<typename MessageType> class Message : public MessageBase
{
virtual void dispatch(HandlerBase* handler)
{
dynamicDispatch(handler, static_cast<MessageType*>(this));
}
};
class AlphaMessage : public Message<AlphaMessage>
{
};
class BravoMessage : public Message<BravoMessage>
{
};
class Sandbox : public Handler<AlphaMessage>, public Handler<BravoMessage>
{
public:
void run()
{
MessageBase* alpha = new AlphaMessage;
MessageBase* bravo = new BravoMessage;
alpha->dispatch(this);
bravo->dispatch(this);
delete alpha;
delete bravo;
}
virtual void process(const AlphaMessage&) {
// cout << "Applying alpha\n";
}
virtual void process(const BravoMessage&) {
// cout << "Applying bravo\n";
}
};
int main()
{
Sandbox().run();
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)