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::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.
  }
}
于 2013-06-07T10:07:39.607 に答える
0

メッセージがデータを返すようにしたいが、たとえば MsgType1 はすべて小文字にし、MsgTyp2 はすべて大文字にする必要がある場合は、MsgBase で仮想関数を作成して、たとえば次のように呼び出すことができます。

virtual char *getData();

この関数は、子クラスで再実装して、データを処理したいことを実行する必要があります。このようにして、基本クラスのポインターでこの関数を呼び出すと、呼び出しの時点で実際のポインターの型に応じて、再実装された機能が得られます。

于 2013-06-07T10:09:27.010 に答える