2012-04-24 38 views
1

我現在處理這種情況下,我有一個消息對象由多個領域的,所以我有一個地圖,我與類字段對象加載:如何檢索派生對象添加到由其超類對象組成的集合中?

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

但在我的協議一個字段可以有序列作爲一種類型,所以我創建了一個FieldSequence類從Field類繼承,然後將其添加到我的消息我這樣做:

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 2012-04-24 16:29:41

+0

@Golita想象你有很多衍生類型,你需要遍歷你的地圖並檢查它們。它不會很有效率或優雅。順便說一句我猜你的FieldSequence在字段上有額外的方法嗎? – juanchopanza 2012-04-24 16:33:28

+0

是的,它絕對是!所以我能做什麼?在自己的地圖上存儲每種類型的字段? – Glolita 2012-04-24 16:44:45

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; 
}; 
相關問題