關於C++對象的自殺——轉載

關於C++對象的自殺


Jason Lee @ csdn

2010-11-05


前兩天看到一個問題,一個類的成員函數是否可以delete this ?
據出題者的意思來看,是認爲這樣的問題一般比較少人會遇到,而這樣就可以瞭解一下對方對未知問題的分析和解決思路。

出於這點,我也想看看自己的思路,所以就先自己思考了一下。
    1. 要使用delete,那麼對象需要使用new來實例化(處於堆中),而不能使用類似DemoCls d;這樣的語句將對象放在棧中;
    2. 成員函數delete this,這樣給了我一種感覺:這個成員函數是不是超出了自己的權限呢?然而進一步想,我認爲delete this純粹代表釋放this指針指向的特定大小的內存空間,告訴內存管理單元這塊內存區域又“自由”了;
基於以上兩點,我認爲由new運算符分配空間得到的對象的成員函數可以調用delete this;語句。

後面在C++ FAQ看到該問題的闡述,原文如下:


[16.15] Is it legal (and moral) for a member function to say delete this?

As long as you're careful, it's OK for an object to commit suicide (delete this).

Here's how I define "careful":

   1. You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new).
   2. You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.
   3. You must be absolutely 100% positive sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).
   4. You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.

Naturally the usual caveats apply in cases where your this pointer is a pointer to a base class when you don't have a virtual destructor.

上面提到了“自殺”時需要注意4點:
    1. 對象是通過最簡單的new運算符分配到空間的,而非new[],也不是內存定位的new(比如new(P) Q),更不是棧上面的、全局的,最後該對象不能是另外一個對象的成員;
    2. 負責自殺的成員函數應該是該對象最後調用的成員函數;
    3. 負責自殺的成員函數在delete this;這一條語句後面不能再去訪問對象的其它成員;
    4. 對象自殺後,不能再去訪問this指針;
最後說明了一句,如果this指針指向一個不具有虛析構函數的基類對象,往往會出現警告。

    對於上面要注意的4點,有的即使不遵守也不會出現警告或者錯誤,但是會有安全隱患。因爲delete this;語句得到調用後,指向該對象的指針就是野指針了,這時候內存中的內容可能保持完整並且可以被訪問,使得數據仍然有效,但是安全的編碼風格應該保證內存釋放後不能再對它進行訪問,避免潛在風險。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章