2016-12-11 4 views
0

C++ 03で、異なるソースからのさまざまな種類のメッセージを管理する必要があるシステムを設計する必要があるとします。オーバーライドされたメソッドで別の列挙型を返す

すべてのメッセージには、IDであるを表す数字が共通してメッセージに含まれるデータのを表します。

したがって、IDはソースに関連し、異なるソースは他のソースの共通IDを持つことができます。 SourceAおよびSourceBは、メッセージ内のデータの意味がまったく違うにもかかわらず、IDが1に設定されたメッセージを送信できます。

だから、メッセージを表す基底クラスには、次のように宣言することができます

enum SourceType { 
    SourceA, 
    SourceB, 
    // ... 
}; 

struct Message { 
    virtual int getID(); 
    virtual SourceType getSource(); 
    // ... 
}; 

私は自分のコードの周りマジックナンバーを広めるために避けたいので、私はいくつかのより有意義にintを交換したいと思いますenumですが、各ソースは独自の異なる列挙型を持つことができません。

によって返された情報を使用して、を適切なenumにキャストしている可能性がありますが、非常に完璧なデザインのようです。そう

enum MessageID { 
    SourceA_ID1, 
    SourceA_ID2, 
    SourceB_ID1, 
    SourceB_ID2, 
    // ... 
}; 

そして:

別の解決策は次のように、(それはエラーではありません)値の重複の多くを持つすべてのソースのためにすべての可能なIDで大きな列挙型を定義することができgetIDメッセージはMessageIDを返す可能性がありますが、これはMessageIDのサイズが爆発的になり、維持管理や文書化が少し面倒かもしれないことを意味します。

+1

したがって、ディスパッチャは 'SourceType'とメッセージIDを使って正しいペイロードタイプをインスタンス化しますか?あなたのデザインを完全に理解しているかどうかはわかりません。メッセージIDを使用したこのような遅延解析は、GoogleプロトコルバッファBTWなどのシステムによって既に実装されています。 –

+0

基本的には、さまざまなソースからのさまざまなメッセージを管理するシステムを構築することです。各ソースは異なる言語を使用するため、解析はカップル(ソース、メッセージID)によって異なります。厳しい制限のある古い組み込みシステム(PowerPC)を使用しているので、サードパーティライブラリを使用することはできません。 –

+0

なぜ 'pair'(または利用可能な場合は' tuple')を返しますか? 1つのコンポーネントはソースの数値IDであり、もう1つはメッセージの数値IDです。この方法では、ペアを受け取るソフトウェアは、最初のコンポーネントを独自のID値にマッチさせてそこから対応する 'enum 'にキャストする方法だけを知っていなければなりません。 –

答えて

1

あなたの最初の選択肢で行く:

一つの解決策は、メソッドgetSourceによって返さ 情報を使用して、適切な列挙型をint型にキャストすることができ、それは非常に完璧な デザインらしいです。

enumは、intと同じです。これは、定数を作成してコード全体のマジックナンバーを避ける簡単な方法として存在します。だから、持つことが可能ません:

enum SourceType { 
    SourceA, 
    SourceB, 
    // ... 
}; 

struct Message { 
    virtual int getID(); 
    virtual SourceType getSource(); 
    // ... 
}; 

// Maybe in "sourceA.h" 
enum SourceA_Ids { 
    SourceA_ID1 = 1, 
    SourceA_ID2 = 12, 
    SourceA_ID3 = 20 
}; 

// Maybe in "sourceB.h" 
enum SourceB_Ids { 
    SourceB_ID1 = 1, 
    SourceB_ID2 = 2, 
    SourceB_ID3 = 3 
}; 

そして、あなたのコードでは、intへのenumは暗黙的であるので、何かをキャストする必要がなく、直接割り当てと比較を行います。

// sourceA.h 
struct MessageFromSourceA: Message { 
    double data; 
    ... 
    MessageFromSourceA() { 
     source = SourceA; 
     data = 0; 
    } 
}; 

// sourceA.cpp 
void processMsgFromSourceA(Message &msg) { 
    if (msg.getID() == SourceA_ID1) { 
     // Send an answer 
     MessageFromSourceA msga; 
     msga.id = SourceA_ID2; 
     msga.data = 123.456; 
     send(msga); 
    } 
} 

ご覧のとおり:魔法の数字、コンパイルエラーはありません。

関連する問題