マルチキャストメッセージを受信し、クラスにデータを解析し、キューを介して別のスレッドに の基本クラスポインタを渡すシステムを更新しています。もう一方のスレッドは、クラスからデータ を読み取り、テーブルに格納します。静的キャストと動的キャストを避ける
私たちが受け取るメッセージは2種類あります。ここでは、クラスのデザインです:
class BaseMsg
{
public:
BaseMsg(char tp) : msgType(tp) {}
virtual ~BaseMsg() = 0;
char msgType;
}
class MsgType1 : public BaseMsg
{
public:
MsgType1(int a, int b) : BaseMsg('1'), val1(a), val2(b) {}
virtual ~MsgType1();
int val1, val2;
}
class MsgType2 : public BaseMsg
{
public:
MsgType2(double a, double b) : BaseMsg('2'), val1(a), val2(b) {}
virtual ~MsgType2();
double val1, val2;
}
ここで受け取るコードは次のとおりです。
void reciveMessage(char *datablob, MsgQueue *queue)
{
BaseMsg *msgReceived;
char type = datablob[0]; // message type is the first character in the data,
// the rest of the blob varies based on that type
if (type == '1') {
// code for parsing type 1 into 2 ints, i1, i2
msgReceived = new MsgType1(i1, i2);
} else {
// code for parsing type 2 into 2 doubles, d1, d2
msgReceived = new MsgType2(d1, d2);
}
queue->push(msgReceived);
}
ここでは別のスレッドで実行されるプロセスのコードは次のとおりです。
void processMessage(MsgQueue *queue)
{
BaseMsg *msgToProcess = queue->pop();
if (msgToProcess->msgType == '1') {
MsgType1 *mt1 = static_cast<MsgType1 *>(msgToProcess);
// do stuff with the message type 1 data
} else {
MsgType2 *mt2 = static_cast<MsgType2 *>(msgToProcess);
// do stuff with the message type 2 data
}
}
私が知っていることをメッセージタイプのチェックがダウンキャスティングはお粗末ですが、 の通信の制約を受けて、私はよりよい解決策を考え出すことができませんでした。ダイナミックキャスト<(パフォーマンス上の理由から 私はしたくない)を使用しても同じ問題が発生します。まだそれを知る必要があります msgToProcessに変換するクラスのタイプ。
キャスト&キャストを取り除く方法についてのご意見はありますか?私はたくさんの経験を持っています C & C++ですが、OOデザインではそれほどではないので、私は何も知らない方法があるかもしれません。
これは、質問を説明するために非常にすっきりした例です。 何百万ものメッセージを毎秒受信できるので、実際には は50種類以上のメッセージタイプであり、パフォーマンスは非常に重要です。
「do stuff」セクションには、あなたがimpできる方法がありますか基本クラスの仮想関数呼び出しの点でそれを尊重しますか? – RyanP
'downcast'が使用されている場所の数を最小限に抑えることはできますが、避けることはできません。繰り返しの少ない方法については、[私の答えは別のSOの投稿](http://stackoverflow.com/a/43038856/434551)を参照してください。 –
RTTI(キャスト)に頼りたくない場合は、区別の付いた共用体を使用することができますが、引き続き列挙型に対してswitch文が必要です。同様のジョブを実行するstd :: variantもあります。私はパフォーマンスを試していませんが、キャッシュのローカリティの恩恵を受けるような間接指定を保存する必要がないため、非常に高速になると思います。 – AlexG