Лучший способ перейти от базового класса к производному классу

Я знаю, что об этом спрашивают по-разному на этом форуме, но я все еще не могу понять, как лучше всего поступить, что мне нужно делать (после прочтения различных других сообщений). Поэтому я решил обратиться за дальнейшими советами!

У меня есть иерархия классов сообщений, что-то вроде (опущено большинство деталей):

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

Есть ли способ, которым я могу смотреть на данные как на базовый класс, чтобы я мог определить их тип и затем «молиморфировать» их в требуемый производный тип?

Спасибо,
фураж

0

Решение

Что такое rxData? Я предполагаю, что это просто блок данных, и вы должны проанализировать его, чтобы определить тип сообщения до Вы создаете любой объект сообщения. И в зависимости от того, имеют ли данные сообщения всегда одинаковую длину, вы должны рассмотреть возможность использования std::array или же std::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.
}
}
1

Другие решения

Если вы хотите, чтобы сообщения возвращали данные, но, например, MsgType1 должен сделать все это строчными, а MsgTyp2 — заглавными, вы можете сделать виртуальную функцию в MsgBase, которая называется, например,

virtual char *getData();

и эта функция должна быть переопределена в дочерних классах, чтобы она делала с данными то, что вы хотите, чтобы они делали. Таким образом, когда вы вызываете эту функцию для указателя базового класса, вы получите переопределенную функциональность, в зависимости от того, какой тип является фактическим указателем, в момент вызова.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector