我知道在这个论坛上有各种各样的问题,但我仍然无法找到最好的方法去做我需要做的事情(阅读其他各种帖子后)。所以我有兴趣寻求进一步的建议!
我有一个消息类层次结构,类似于(省略了大多数细节):
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”转换为所需的派生类型?
谢谢, 饲料
答案 0 :(得分:1)
什么是rxData
?我认为它只是一个数据块,您应该解析它以确定之前的消息类型您创建任何消息对象。根据消息数据是否始终具有相同的长度,您应该考虑使用std::array
或std::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();
并且应该在子类中重新实现此函数,以便它可以使用您希望它执行的数据。这样,当您在基类指针上调用此函数时,您将获得重新实现的功能,具体取决于实际指针在调用时的类型。