如何根据特定对象的类型调用特定函数

时间:2010-05-04 02:21:59

标签: c++ messages

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

给定一个任意的Message*对象,如何调用同名doMessage()的函数而不依赖于切换逻辑或者为每个消息名创建一个'do'函数的MessageHandler类?

编辑:例如:

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

对不起我以前不清楚。

编辑:

有人可以删除这个问题的火车残骸吗?我真的不希望所有这些高中课程都是多态的。

5 个答案:

答案 0 :(得分:8)

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

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

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

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

handler_map[m.name()]();

我会使用Boost :: function在地图中存储函数指针。


OLD ANSWER:我认为您需要的是虚拟功能:

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();

它将输出“建造沙堡”。

答案 1 :(得分: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 */ }
};

答案 2 :(得分: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

答案 3 :(得分:0)

听起来像家庭作业,所以你应该看看virtual函数(wikipedia)。消息应该具有纯虚拟doMessage,它将在子类中被覆盖。

答案 4 :(得分:0)

我在找this

之类的东西
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或传递消息本身(原始问题中的代码。)