将来在另一个类中调用虚方法

时间:2017-11-07 15:11:21

标签: c++

我有一个界面,我们可以称之为“服务器”

class MsgHandler {
 public:
  virtual void handleMsg1(int x) = 0;
  virtual void handleMsg2(int x) = 0;
  virtual void handleMsg3(int x) = 0;
};

class Server {
 public:
  void setMsgHandler(MsgHandler *h) { currentHandler = h; }
  MsgHandler* getMsgHandler() { return currentHandler; }
 private:
  MsgHandler *currentHandler;
};

和一个HandlerA类:

class HandlerA : public MsgHandler {
 public:
   HandlerA(Server& s) : server(s) {}
   void handleMsg1(int x) override { /* do something */ }
   void handleMsg2(int x) override { 
     // do something more
     server.setMsgHandler(new HandlerB(s)); // Note that we change Handler here!
   }
   void handleMsg3(int x) override; // I'll come back to this below
 private:
   Server &server;
};

和HandlerB:

class HandlerB : public MsgHandler {
 public:
   HandlerB(Server& s) : server(s) {}
   void handleMsg1(int x) override { /* do nothing */ }
   void handleMsg2(int x) override { /* do nothing */ }
   void handleMsg3(int x) override { /* do something really complex here */ }
 private:
   Server &server;
};

现在,让我们假设我有一个类似这样的应用程序

Server s;
s.setMsgHandler(new HandlerA(s));
s.getMsgHandler()->handleMsg1(0); // Handled by HandlerA
s.getMsgHandler()->handleMsg2(43); // Handled by HandlerA
s.getMsgHandler()->handleMsg3(99); // Handled by HandlerB

到目前为止一切顺利。但是,我们假设我的应用程序是任意的/非确定性的,因此我们有时可能会得到这个序列:

Server s;
s.setNextMsgHandler(new HandlerA(s));
s.getMsgHandler()->handleMsg1(0);
s.getMsgHandler()->handleMsg3(99); // msg3 comes before msg2!!
s.getMsgHandler()->handleMsg2(43);

我想在HandlerA中做的事情是这样的:

void HandlerA::handleMsg3(int x) {
  putMsgInQueue(MsgHandler::handleMsg3, x); // pseudo code!
}

然后我可以通过队列,也许做这样的事情

s.setNextMsgHandler(new HandlerA(s));
s.getMsgHandler()->handleMsg1(0);
s.getMsgHandler()->handleMsg3(99); // msg3 comes before msg2, no problem
s.getMsgHandler()->handleMsg2(43);
processMsgFromQueue(s.getMsgHandler(), ...);

这个排队会简化我的代码,因为handleMsg3()可能非常复杂,并且可能还需要我在handleMsg2()中获得的信息。

我的问题是:如何实现putMsgInQueue(...)/ processMsgFromQueue()或类似的东西?我想我想要一种方法来保存对虚方法的引用在基类中。稍后当我想调用该方法时,调用它实际上会导致对子类的调用。

在给出过于简单/过于复杂的答案之前,请考虑以下事项: - )

  • 解决方案需要是通用的,即我想排队任何handleMsgX(...)
  • 我们可以假设MsgHandler中的所有handleMsgX()方法看起来都一样,即它们都返回void并且它们都具有相同的参数
  • 请记住,在调用putMsgInQueue()时,不存在HandlerB实例。它是在稍后创建的!

0 个答案:

没有答案