Design pattern to avoid downcasting in message passing

前端 未结 3 1539
孤城傲影
孤城傲影 2021-02-06 18:39

Base class MessageHandler has derived classes. They would like to pass messages to each other. Messages could be of different classes, but can be made to share a ba

3条回答
  •  广开言路
    2021-02-06 19:29

    This is pretty easy to do. There are generally two alternatives:

    Boost.Variant

    Instead of passing a derived class, simply enumerate the possible types that a message could be. These types need not be derived from one another. Wrap those types in a boost::variant:

    typedef boost::variant MessageData;
    

    Note that this means that the possible message data types must be enumerable. Boost.Variant's visitation methods make it easy to work with objects of these types without knowing exactly which type it stores.

    Boost.Any

    Simply pass anything with a boost::any:

    void MessageHandler::receiveMessage(const boost::any &msg)
    {
      const MessageType1 *pMsg = boost::any_cast(&msg);
      if(!pMsg)
        //Cannot process
        return;
    
      //Process message.
    }
    

    boost::any is like a type-safe void*. It remembers the exact type that was put into it, and any attempt to cast it to something other than what is stored in it will fail. boost::any can store anything, hence the name.

    It also has value semantics, so it can be copied like its contents.

提交回复
热议问题