1
class Message {};
class BuildSandCastle : public Message {};
class DigHole : public Message {};

给定一个任意Message*对象,我怎样才能调用同名函数doMessage()而不求助于切换逻辑或创建一个 MessageHandler 类,该类对每个消息名称都有一个“do”函数?

编辑:例如:

class Sandbox
{
public:
  void play(Message* m)
  {
     // call doBuildSandCastle
     // or doDigHole based on m's type
  }
  void doBuildSandCastle();
  void doDigHole();
};

抱歉我之前没有说清楚。

编辑:

有人可以删除这个问题的火车残骸吗?我真的不想要所有这些关于多态性的高中课程。

4

5 回答 5

8

编辑:既然问题已经澄清,这是新的答案:

您可以让您的消息对象调用正确的函数:

void play(Message* m) { m->play(this); } 

或者您可以在 Sandbox 中有一个函数指针映射,并根据消息名称(或 typeid)执行适当的函数,例如

handler_map[m.name()]();

我会使用 Boost::function 将函数指针存储在映射中。


旧答案:我认为您需要的是虚拟功能:

class Message 
{
  virtual void doMessage { std::cout << "message" << std::endl; }
};
class BuildSandCastle : public Message 
{
  virtual void doMessage { std::cout << "build sand castle" << std::endl; }
};
class BuildSandCastle : public Message 
{
  virtual void doMessage { std::cout << "dig hole" << std::endl; }
};

当你doMessage这样打电话时:

Message* msg = new BuildSandCastle();
msg->doMessage();

它将输出“建造沙堡”。

于 2010-05-04T02:27:08.170 回答
2

听起来您只是想向某些类添加多态函数。假设子类上的任何参数和返回值都相同,您可以在基类中添加一个纯虚函数。

例如:(注意:我没有编译这个,如果有错别字,请见谅)

class Message
{
    public:
    virtual void doMessage() = 0;
};

class BuildSandCaste : public Message
{
    public:
    void doMessage() { /* build a sand castle */ }
};

class DigHole : public Message
{
    public:
    void doMessage() { /* dig hole */ }
};
于 2010-05-04T02:30:09.623 回答
0

使用虚函数。

class Message {
  virtual void doSomething(...) = 0;
};

class ReportMessage : public Message {
  virtual void doSomething(...) {
  // (...) - specific for repors
  }
};

class BankReportMessage : public ReportMessage {
  virtual void doSomething(...) {
  // (...) -||- for banks
  }
};

现在,在您的代码中的某处:

Message* my_message = new BankReportMessage(...);
my_message->doSomething(...); // Would call appropriate function
于 2010-05-04T02:26:14.880 回答
0

听起来像家庭作业,所以你可能应该看看virtual函数(维基百科)。Message 可能应该有纯 virtual doMessage,它在子类中被覆盖。

于 2010-05-04T02:27:00.027 回答
0

我一直在寻找这样的东西

class MessageHandlerBase
{};

template<typename MessageType>
class MessageHandler:
    public virtual MessageHandlerBase
{
    virtual void process(MessageType*)=0;
};

class Message
{
protected:
    template<typename MessageType>
    void dynamicDispatch(MessageHandlerBase* handler,MessageType* self)
    {
        dynamic_cast<MessageHandler<MessageType>&>(*handler).process(self);
    }
};
class Message1:
    public MessageBase
{
    void dispatch(MessageHandlerBase* handler)
    {
        dynamicDispatch(handler,this);
    }
};

除了不必使用 dynamic_cast 或传递消息本身(如原始问题中的代码)。

于 2010-05-04T04:08:14.857 回答