2009-10-28 67 views
6

我在處理現有庫時遇到了析構函數的奇怪用法。被分配stl向量的棧的析構函數被明確調用,當它的情況下該對象可能需要再次使用。這些矢量對象是具有專門的clear方法的stl矢量類的稍微定製的版本。在析構函數體中存在兩個方法調用:clear(),_Tidy()C++堆棧分配對象,顯式析構函數調用

我一直在想爲這個析構函數被調用的一個很好的理由,而不僅僅是clear,但我不知所措。任何人都清楚爲什麼這可能是一個好主意?

+0

你能提供一個代碼示例,向量dtor的代碼示例,以及它如何被調用? – 2009-10-28 16:43:01

+3

_Tidy()做了什麼? – Brian 2009-10-28 16:44:18

+0

向我們展示矢量是如何創建的。 – sbi 2009-10-28 17:07:10

回答

1

這絕對不是一個好主意。析構函數開始運行後對對象的任何操作都會產生未定義的行爲。

+0

或者說,析構函數完成後?我想如果你在實例的任何其他地方和超出範圍之前在放置new的同一個地方構造另一個實例,這可能是有效的。 – UncleBens 2009-10-28 16:49:51

+0

這些操作包括在作用域結束時自動調用dtor。 – sbi 2009-10-28 17:06:38

+0

@UncleBens:不,一旦析構函數啓動,你應該考慮你的對象不再存在...嘗試使用基類的析構函數中的虛函數,它實際上使用派生類的堆分配內存......參見我的意思是 :) ? – 2009-10-28 18:51:59

5

這個班可以使用某種placement new方法嗎?這是我唯一一次傾向於看到正在使用的顯式析構函數。

+0

在我寫作的時候打敗了我。 ;) – John 2009-10-28 16:47:53

1

也許最初的編碼人員關心內存分配對象的位置。

然後必須明確調用析構函數,按照this discussion

+0

這可能是這種情況,因爲討論是關於堆棧分配向量的。 – 2009-10-28 18:53:14

5

大矢量?

瘋狂的猜測......當clear()被稱爲矢量通常是空的,但內存沒有釋放。這就是爲什麼有這樣的模式

std::vector<T>().swap(vector_to_clear); 

清空向量重用和清除分配的內存。

也許原來的作者並不知道這個模式,並試圖用這種邪惡的方式擺脫分配的內存。 (我認爲_Tidy可以釋放分配的內存)

+0

矢量大小不一,但沒有太大的。 我很想知道原作者的意圖,希望它只是一個誤導的內存釋放 – Colin 2009-10-28 17:14:14

+0

我的第一個問題是這樣的情況是:什麼是簽入評論? – sbi 2009-10-29 09:26:09

9

clear()不保證實際釋放向量中分配的存儲空間; MSVC實現中的_Tidy()實際上將釋放該存儲空間,所以這可能是作爲優化完成的。

這是一件很糟糕的事情,但只要存儲被相同類型的對象(忽略cv-qualifiers)重用存儲併合法地存儲所有的存儲空間,您就可以合法地執行此操作:

T automatic; 
automatic.T::~T(); 
new (&automatic) T(); 

C++標準的第3.8.7節描述了這種使用場景並解釋了它是如何合法的;它甚至包括一個類似於上面的例子。