假設我有一個STL向量,其元素是指向其他類的原始指針。很明顯,向量的析構函數不會釋放這些指針所擁有的內存。是否有可能實現一個釋放這個內存的自定義析構函數?STL容器中的自定義析構函數
回答
在現代C++中,使用vector<unique_ptr<T>>
,併爲您管理所有所有權問題。
如果C++ 11不可用,您可以使用shared_ptr
(來自Boost或TR1)而不是unique_ptr
,或者您可以使用Boost's pointer containers。 (不要試圖使用已棄用的auto_ptr
,因爲這樣做太容易從容器中意外刪除指針了。假設第一條評論指的是這個,但將它與更安全的unique_ptr
混淆。)
如果由於某種原因,你不能使用這些,或者如果你真的想自己做的工作,你需要與包裹載體的一類:
- 刪除的每個存儲的指針析構函數;
- 複製構造函數和複製賦值運算符,或者被刪除,或者執行「深度」複製;否則,存在兩個向量認爲他們擁有相同對象的危險;
- 訪問器以這種方式讀取和修改元素,使得您不能覆蓋存儲的指針而不刪除其對象。
使用'unique_ptr'確實是個問題。它在容器中不能很好地工作,因爲'auto x = v [i];'或'auto x = * iter;'會在容器中給你一個無效的'unique_ptr'。 – 2013-03-25 12:47:47
@JamesKanze:不會的,因爲那不會編譯。 'auto x = move(v [i])'會將'unique_ptr'移出容器;但大概這就是你明確使用'move'的意圖。 – 2013-03-25 12:49:06
@JamesKanze:除了在玩具程序中,我還沒有真正使用C++ 11的特性,但我的理解是'std :: unique_ptr'是爲了解決這個特殊問題而設計的。是什麼讓這個糟糕的(甚至是最糟糕的)解決方案? – 2013-03-25 13:16:12
您需要通過在刪除矢量進行迭代,並調用每個元素的析構函數裏面
或者我想最好的辦法是,而不是保存A *,保存shared_ptr<A>
然後沒人的時候不再指向A,它將被破壞
一個小警告:std :: vector沒有虛擬析構函數。 – 2013-03-25 12:26:02
嗯,以爲這是因爲某種原因,謝謝編輯 – Alon 2013-03-25 12:26:55
不可以。您應該在破壞矢量之前手動清除元素。像
std::for_each(v.begin(), v.end(), [](const T* p) { delete p; });
,或者您可以使用類似boost::ptr_vector
(或某些smart_pointers)的東西,即處理這種情況。
如果你有C++ 11,使用'std :: unique_ptr'比使用lambda進行清理手動更清潔。 – 2013-03-25 12:36:33
@DavidRodríguez-dribeas當然。 – ForEveR 2013-03-25 12:37:26
@DavidRodríguez-dribeas使用'unique_ptr'是我能想到的最糟糕的解決方案之一。 – 2013-03-25 12:45:33
- 1. 爲什麼STL容器沒有虛擬析構函數?
- 2. Delphi自定義組件析構函數
- 3. 使用自定義分配器調用對象構造函數/析構函數
- 4. 移動自定義容器的構造函數?
- 5. Doctrine2 Symfony2自定義函數解析器
- 6. 從STL容器中移除元素時調用析構函數嗎?
- 7. 從Unity容器中自動解析構造函數參數
- 8. stl map <char*,char*>析構函數
- 9. STL迭代器到構造函數中
- 10. STL允許在一個容器的元素上多次調用析構函數
- 11. 構造函數在自定義適配器中未定義
- 12. Luabind中的自定義構造函數
- 13. 用於C++ STL中的SORT的自定義比較函數?
- 14. STL容器上的C++模板函數
- 15. C++自定義分配器和STL容器
- 16. 對構造函數和析構函數的未定義引用
- 17. stl的自定義比較器
- 18. 如何使用自定義IOC容器中的構造函數參數解析實例?
- 19. STL容器:構造函數的分配器參數和作用域分配器
- 20. 「已經定義的析構函數」與專門的析構函數
- 21. C++在迭代器類中定義析構函數?
- 22. 使用仿函數沒有對STL容器的默認構造函數
- 23. STL容器函數返回值
- 24. 用lambda函數排序stl容器
- 25. Xcode未定義符號〜析構函數
- 26. 對STL容器行爲從自定義模板類
- 27. 解析Java中的自定義結構
- 28. 更改自定義函數的內容
- 29. STL地圖自定義比較器
- 30. 與自定義模板STL迭代器
你需要的不僅僅是一個析構函數(以及三條規則的其餘部分);您還需要非常小心,不要因重新分配元素而丟失指針。有關血淋淋的細節,請參閱Boost指針容器的實現;在現代C++中,只需使用'vector'。 –
2013-03-25 12:24:52
@MikeSeymour無論你做什麼,都不要在容器中使用'unique_ptr'。遲早,你肯定會做一些像'auto x = v [i];',從容器中有效地移除指向的對象。如果您必須使用'shared_ptr',但Boost指針容器是一個更好的解決方案,在極少數情況下容器應擁有這些對象。 – 2013-03-25 12:45:01
@JamesKanze:你在想'auto_ptr',哪些(現在這些日子)你不應該使用任何東西?使用唯一的指針,'auto x = v [i]'不應該在沒有明確的'move'的情況下編譯。 – 2013-03-25 12:46:15