开发者

In method / function overloading, must every version be reimplemented?

I want to implement double dispatch. Say I have a class like so:

class Entity
{
   public:
   virtual void eventHandler(Message* msg, Entity* entity);
}

Then eventually I create derived entities. Say I eventually create several different types which开发者_如何转开发 derive from Entity. Do I need to forward declare them all in Entity.hpp then make methods for each one? What if my class names change, it seems to add a maintenance overhead?

The other thing I was wondering is if I need to re implement each one in each class.

Say Player needs to respond to the event handler of an Item. Does that mean I need to provide empty implementations for all the other ones?

Thanks


In double-dispatch you have two class hierarchies, A and B. A has a bunch of overloaded methods that take different versions of B and B has a single method that takes A. Each of these methods need one argument. You need to declare all different versions in the A base class and implement all of them in A derived classes. You also need to reimplement the B method in each B derived class. Yes this means A knows about each one of the B versions in advance.

Let's say you have 3 concrete messages, a KeyboardMessage, a MouseMessage ans a ScreenMessage. You also have a growing family of Entities, at this time it consists of a Widget and a Gadget. In a C++-like pseudocode

class Message { virtual void dispatch(Entity* e) = 0 }
class KeyboardMessage : Message { void dispatch(Entity* e) { e->process(this); }}
class MouseMessage : Message { void dispatch(Entity* e) { e->process(this); }}
class ScreenMessage : Message { void dispatch(Entity* e) { e->process(this); }}

class Entity
  {
     virtual void process (KeyboardMessage* m) {... default impl...}
     virtual void process (MouseMessage* m) {... default impl...}
     virtual void process (ScreenMessage* m) {... default impl...}
  }

 class Widget : Entity
  {
     void process (KeyboardMessage* m) {... impl...}
     void process (MouseMessage* m) {... impl...}
     void process (ScreenMessage* m) {... impl...}
  }

class Gadget : Entity
  {
     void process (KeyboardMessage* m) {... impl...}
     void process (MouseMessage* m) {... impl...}
     void process (ScreenMessage* m) {... impl...}
  }

Now you can add other concrete entities with ease. To add another message, you will have to add a method to Entity, possibly reimplement it in some derived classes, but recompile all derived (since the base has changed).

See, no casts here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜