2012-11-14 60 views
5

這可能看起來很奇怪,但我會盡量合理化它。我目前使用boost.object_pool廣泛地與shared_ptr一起使用,最近我遇到了一種情況,我需要拍攝當前程序狀態的快照,以便使功能像全面的重播/回滾/快進C或C++中的任何可克隆對象池實現?

所以我不想克隆一個對象池在其他地方使用,這不會明顯工作,因爲即使我被boost.pool的接口(我不是)允許我這樣做,將不會有效指向那個新克隆池中的塊的指針,這將是毫無意義的。但我的用例在這裏是我想要「粘貼」它回到原始池,如果有重放/回滾的需要。

我當然可以手動複製並克隆所有狀態,對象和子狀態,子對象和subsub ...,然後將它們打包成快照,並希望一切都會正確,但這是錯誤的,因爲項目已經有了複雜性,所以它要比直接複製內存慢得多。使用Command模式(或類似的)來實現撤銷重做也是不可能的,因爲撤消重做機制不是我的意圖。

我只是想知道如果我使用頑固的傳統C方法再次從頭開始項目,並且簡單的memcpy(snapshot,all_states,size)調用幾乎可以完成所有工作。

有沒有其他的選擇,我仍然失蹤?是否有任何boost.object_pool像實現,允許您克隆底層內存區域?考慮到這種情況,侵入性地攻擊boost.object_pool是一個合理的選擇嗎?

+0

用相似的界面編寫自己的,可複製的對象池似乎並不困難或耗時。 – Pubby

+0

@Pubby:圖形結構從來都不容易克隆。最常見的錯誤是陷入無限循環,無意中破壞了圖表。調試也太糟糕了。 –

回答

2

不是我所知道的。

正如您所指出的那樣,這裏的主要問題是在進行復制時需要更新指針的對象之間存在可能的相互依賴關係。當然不平凡。

我能想到的兩種可能的解決方案:

  • 持久性
  • 系列化

持久性大約是從來沒有變異存在狀態。當你改變狀態時,你就創建了一個新的快照,除了新的位之外,它指向舊的狀態。例如,它通常用於數據庫的MVCC實現,並且在函數式編程世界中非常普遍。如果您嘗試保留太多引用,這也是獲取空間泄漏的好方法。最後,它需要深度重新設計。

序列化是關於持久狀態,但格式不同。以序列化格式(無論是文本還是二進制)轉儲當前狀態,並且可以通過讀取序列化緩衝區來重新創建它。您甚至可以在序列化緩衝區上應用壓縮過程來節省一些內存。

既然您已經在使用Boost,那麼很高興知道Boost.Serialization會自動處理對象圖(eh!),我認爲它已經正確處理了boost::shared_ptr。這可能是您的最佳選擇。