2016-09-18 19 views
2

(例如,在使用線程構建模塊的內存池)如果容器和分配器都是同一個內存池的一部分,我還需要調用std :: container的析構函數嗎?

可以說我有以下設置:

using MemoryPool = tbb::memory_pool<std::allocator<char>>; 
using CustomAllocator = tbb::memory_pool_allocator<Result*>; 
using CustomVector = std::vector<Result*, CustomAllocator>; 

MemoryPool shortTermPool; 
void* allocatedMemory = shortTermPool.malloc(sizeof(CustomVector); 
CustomVector* results = static_cast<CustomVector*>(allocatedMemory); 
new(results) CustomVector(CustomAllocator(shortTemPool)); 

後來我打電話

shortTermPool.recycle(); 

這行代碼回收所有的內存內存池,允許我重用它。現在,既然矢量和它的分配器都在使用內存池,我是否仍然需要在回收內存池之前調用

results->~vector(); 

?析構函數是否做了其他任何事情,或者將整個池回收足夠嗎?

+0

是的。您可以安全地假定,在對象的存儲被破壞之前,所有對象都有必須執行的析構器操作。你使用placement new來構造一個對象。所有構建的對象都必須銷燬。調用對象的析構函數是實際銷燬它的必需部分。 –

+0

假設我不在上面的例子中調用析構函數。內存中爲矢量結果留下了什麼。內存池中的內存中是否有東西被分配? (假設任何Result *對象也是使用同一個內存池構造的))。 – user1432882

+0

除非調用析構函數,否則會導致未定義的行爲。如果你想驗證這對你的特定C++實現沒有任何不良影響,那麼繼續吧。但是答案僅限於你的C++實現。調用析構函數不是一項艱鉅的任務。這很容易。而且,這將避免意想不到的驚喜,未來,基本容器應該被更復雜的東西所取代。 –

回答

1

從C++標準:

3.8對象壽命

的程序可以通過重新使用該對象佔據存儲或通過顯式 調用結束任何對象的生命週期具有非平凡析構函數的類類型對象的析構函數。 對於具有非平凡析構函數的類類型的對象,在對象佔用的存儲被重用或釋放之前,不需要顯式調用析構函數;然而,如果 沒有對析構函數的顯式調用,或者沒有使用刪除表達式 (5.3.5)來釋放存儲空間,那麼析構函數不應該被隱式調用,並且任何依賴於副作用的程序都會被調用 由析構函數生成的行爲不確定。

這取決於是否std::vector析構函數是非平凡的,並有副作用程序依賴。因爲它是一個庫類,建議調用析構函數以保證安全。否則,您現在必須檢查std::vector的實現,以確保您的代碼與所有標準庫兼容。
如果矢量類是你自己的,那麼你將控制析構函數的實現,如果它不重要,或者沒有程序依賴的副作用,你可以省略它的調用,如上所述。
(但我個人也會在這種情況下稱之爲)。

+3

供參考:std :: vector的析構函數不是微不足道的,正如標準所要求的那樣。 –

相關問題