0

我知道这个论坛上以各种方式提出了这个问题,但我仍然无法弄清楚我需要做什么的最佳方式(在阅读了其他各种帖子之后)。所以我决定寻求进一步的建议!

我有一个消息类层次结构,类似于(省略大部分细节):

class MsgBase
{
    public:
        uint8_t getMsgType(void);

    protected: // So that derived classes can access the member
        char _theMsgData[100];
}

class MsgType1 : public MsgBase
{
}

class MsgType2 : public MsgBase
{
}

所以会发生什么是我收到了一个消息数据块,我用它来创建我的消息。但是在我读出消息类型之前,我不知道要创建哪个消息。所以我最终得到:

MsgBase rxMsg(rxData);
if (rxMsg.getMsgType() == 1)
{
    // Then make it a MsgType1 type message
}
else if (rxMsg.getMsgType() == 2)
{
    // Then make it a MsgType2 type message
}

这是我坚持的一点。根据我的阅读,我无法从基础动态转换为派生。所以我目前的选择是实例化一个全新的派生类型(这似乎效率低下),即:

if (rxMsg.getMsgType() == 1)
{
    // Now use the same data to make a MsgType1 message.
    MsgType1 rxMsg(rxData);
}

有没有一种方法可以将数据视为基类,以便确定其类型,然后将其“变形”为所需的派生类型?

谢谢,饲料

4

2 回答 2

1

是什么rxData?我假设它只是一个数据块,您应该在创建任何消息对象之前对其进行解析以确定消息类型。并且根据消息数据是否始终具有相同的长度,您应该考虑使用std::arraystd::vector传递数据块。

typedef std::vector<char> MsgDataBlob;

class MsgBase
{
    public:
        uint8_t getMsgType();
        MsgBase(MsgDataBlob blob) : _theMsgData(std::move(blob)) {}

    protected: // So that derived classes can access the member
        MsgDataBlob _theMsgData;
};

//derived classes here...

//this could be either a free function or a static member function of MsgBase:
uint8_t getMessageType(MsgDataBlob const& blob) { 
  // read out the type from blob
}

std::unique_ptr<MsgBase> createMessage(MsgDataBlob blob) {
  uint8_t msgType = getMessageType(blob);
  switch(msgType) {
    case 1: return make_unique<MsgDerived1>(std::move(blob));
    case 2: return make_unique<MsgDerived2>(std::move(blob));
    //etc.
  }
}
于 2013-06-07T10:07:39.607 回答
0

如果您希望消息返回数据,但例如 MsgType1 应该全部小写,而 MsgTyp2 全部大写,您可以在 MsgBase 中创建一个虚函数,例如,

virtual char *getData();

并且这个函数应该在子类中重新实现,以便它对数据做你想做的事情。这样,当您在基类指针上调用此函数时,您将在调用时获得重新实现的功能,具体取决于实际指针的类型。

于 2013-06-07T10:09:27.010 回答