1

私は今、いくつかのフィールドで構成されるメッセージオブジェクトがあるこの状況に対処しているので、クラス Field のオブジェクトでそれをロードするマップがあります:

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

しかし、この変換が原因でエラーが発生しました。元の形式を取得するにはどうすればよいですか、それともスーパークラス形式であるため、マップに追加すると完全に失われますか?

4

2 に答える 2

3

結果を使用dynamic_castして確認できます。

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

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

于 2012-04-24T15:55:42.597 に答える
0

これは非常に一般的な問題です。実際の問題は、Field* ポインターから「派生クラスを取得する」ことではありません。本当の問題は、Field クラスのインターフェイスがすべての派生クラスの動作を適切に表現できないことです。1つの代替案は次のとおりです。

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

もう1つは次のようなものです。

class Field {
public:
    virtual char *Buffer() const=0;
    virtual int BufferSize() const=0;
};
于 2012-04-24T17:48:49.060 に答える