2013-10-02 37 views
0

我有一組類:Value,ReportItem,ReportMessage。值類是抽象的與多個不同的具體實施方式(例如INTVALUE,的floatValue,的doubleValue等)的具體的類被添加到當它被傳遞一個參考值產生的ReportItem的:您能否從抽象參考創建具體對象的副本

ReportItem(Value& value); 

然後ReportItems添加使用「的addItem」方法的ReportMessage,這需要的報表項目的副本和松鼠它扔掉:

class ReportMessage { 
    ... 
    void addItem(ReportItem item); 
} 

所以一段代碼可能是這樣的:

IntValue value(1); 
ReportItem item(value); 

ReportMessage message; 
message.addItem(item); 

我沒有創建ReportItem的副本的問題,但由於它是一個抽象類,所以Value有問題。當創建ReportItem時,它將引用Value對象並保存到該引用上,直到ReportItem被刪除。這是問題所在,因爲如果在ReportItem完成之前刪除Value對象,則地球將從其軸線脫落並螺旋進入太陽。

有沒有解決這個問題的好方法?我想要的是一種引用Value對象(值爲&)的方法,並以某種方式創建具體對象的副本,然後由該報告項目保留該副本。這是可能的,還是有更好的方法。

謝謝。

注意:我沒有使用C++ 11。

+2

只是讓'ReportItem'自己的價值,並通過基類指針處理它。 –

+1

將它作爲一個指針可以處理[clone pattern](http://en.wikipedia.org/wiki/Prototype_pattern)的複製。 – BartoszKP

回答

1

作爲一個簡化示例,您可以通過以下方法使ReportItem類擁有該值。您需要在複製和賦值語義(「虛擬拷貝構造函數」等)努力工作,但我留給你的工作了(即上搜索這個網站現有的答案):

class ReportItem 
{ 
    Value * vptr; // vptr is the first thing in the class 
public: 
    ReportItem(int n) : vptr(new IntValue(n)) { } 
    ReportItem(float x) : vptr(new FloatValue(x)) { } 
    ~ReportItem() { delete vptr; } 

    // write difficult copy and assignment logic! 
}; 

由於沒有C + +11使得它比需要的更麻煩,因爲你沒有明智的移動語義,並且可能需要製作大量不必要的副本。

(在C++ 11,你只需有一個std::unique_ptr<Value>成員,沒有明確的析構函數,你可以說message.addItem(ReportItem(1.5));

+0

這對我不起作用,因爲我必須處理值派生類,而不是原始類型。我認爲克隆模式可能是我必須使用的。 – DaveR

+1

該類可以修改爲採用模板構造函數。 – jxh

+0

如果你沒有C++。11,你可以使用Boost的'shared_ptr <>'代替。它將提供適當的析構函數,複製和分配語義,但它確實增加了引用計數操作的成本。 – jxh