从基类更改为派生类的最佳方法

时间:2013-06-07 09:53:23

标签: c++ base derived

我知道在这个论坛上有各种各样的问题,但我仍然无法找到最好的方法去做我需要做的事情(阅读其他各种帖子后)。所以我有兴趣寻求进一步的建议!

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

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

有没有办法可以将数据作为基类查看,以便我可以确定其类型,然后将其“molymorph”转换为所需的派生类型?

谢谢, 饲料

2 个答案:

答案 0 :(得分:1)

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

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.
  }
}

答案 1 :(得分:0)

如果你想让消息返回数据,但是例如MsgType1应该全部为小写,而MsgTyp2全部为大写,你可以在MsgBase中调用一个虚函数,例如,

virtual char *getData();

并且应该在子类中重新实现此函数,以便它可以使用您希望它执行的数据。这样,当您在基类指针上调用此函数时,您将获得重新实现的功能,具体取决于实际指针在调用时的类型。