2012-04-24 8 views
1

スーパークラスオブジェクトで構成されるコレクションに追加された派生オブジェクトを取得するにはどうすればよいですか?私はクラスのフィールドのオブジェクトでそれをロードマップを持っているので、私はフィールドの数で構成メッセージオブジェクトを持っている。このような状況で、今扱ってい

std::map<int,Field*> myMsg; 

が、私のプロトコルでフィールドには、タイプとしてシーケンスを持つことができるので、私はFieldクラスから継承FieldSequenceクラスを作成し、その後、私はこれをしなかった私のメッセージに追加する:

FieldSequence* seqFld=new FieldSequence(sequence); 
myMsg[seqFld->id]=seqFld; 

が、その後私は私のフィールドを取得するために必要なそのid属性を0値に設定していることがわかっている元のシーケンス形式。私はこれでした:

std::map<int,Field*>::iterator it; 
for (it=myMsg.begin() ; it != myMsg.end(); it++) 
{ 

    cout << "field id => " << (*it).first << endl; 
    int idprm=((*it).second)->id; 
    if(idprm==0) 
    { 
     FieldSequence* temp=(*it).second; 
    } 
} 

を、私はそう何を、私は私の元の形式を取得するために行うことができますか、それはスーパークラスのフォーマットだと、私は自分のマップに追加したら、それは良いのために消えて、これによる変換にエラーがありますか?

答えて

3

あなたはdynamic_castを使用して、結果をチェックすることができます

FieldSequence* temp = dynamic_cast<FieldSequence*>(it->second); 
if (temp) { 
    // do stuff 
} 

をしかし、一般的に、これはあなたがデザインを再考する必要がありサインです。多くの派生型があり、それらをすべてチェックする必要がある場合は、非常にうまく拡張できません。基底クラスへのポインタのコンテナは、すべての派生型が同じインタフェースを実装し、追加のメソッドを持たない場合に最も強力です。

+0

おかげで、私はあなたがあなたが多くの派生している場合は、「それは非常によくスケールしないと言って理解していなかった一つの選択肢は、このことだろうすべてをチェックする必要があります。 – Glolita

+0

@Glolitaはあなたが多くの派生型を持っていたと想像してください。あなたはマップをループしてそれらのすべてをチェックする必要がありました。非常に効率的で優雅ではありません。ところで、あなたのFieldSequenceはフィールドの上に余分なメソッドを持っていると思いますか? – juanchopanza

+0

はい、それは絶対にあります!じゃあどうすればいい ?各タイプのフィールドを独自のマップに在庫しますか? – Glolita

0

これは非常に一般的な問題です。実際の問題は、Field *ポインタから「クラスを派生させる」ことではありません。実際の問題は、Fieldクラスのインターフェイスが、派生クラスのすべての動作を正しく表すことができないことです。このようなものになるだろう

class Field { 
public: 
    virtual std::string ContentsAsString() const=0; 
}; 

別:働い

class Field { 
public: 
    virtual char *Buffer() const=0; 
    virtual int BufferSize() const=0; 
}; 
関連する問題