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

任意のオブジェクトが与えられた場合、ロジックを切り替えたり、メッセージ名ごとに1つの「do」関数を持つMessageHandlerクラスを作成したりせずにMessage*、同じ名前の関数を呼び出すにはどうすればよいですか?doMessage()

編集:例:

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

または、サンドボックスに関数ポインタのマップを作成し、メッセージ名(またはタイプID)に基づいて適切な関数を実行することもできます。

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関数(ウィキペディア)を見る必要があります。メッセージにはおそらく純粋な仮想が含まれている必要が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 に答える