在類的成員函式中呼叫delete this

2021-06-22 04:42:15 字數 2271 閱讀 7119

在類的成員函式中能不能呼叫delete this?答案是肯定的,能呼叫,而且很多老一點的庫都有這種**。假設這個成員函式名字叫release,而delete this就在這個release方法中被呼叫,那麼這個物件在呼叫release方法後,還能進行其他操作,如呼叫該物件的其他方法麼?答案仍然是肯定 的,呼叫release之後還能呼叫其他的方法,但是有個前提:被呼叫的方法不涉及這個物件的資料成員和虛函式。說到這裡,相信大家都能明白為什麼會這樣 了。

根本原因在於delete操作符的功能和類物件的記憶體模型。當乙個類物件宣告時,系統會為其分配記憶體空間。在類物件的記憶體空間中,只有資料成員和虛函式表指標,並不包含**內容,類的成員函式單獨放在**段中。在呼叫成員函式時,隱含傳遞乙個this指標,讓成員函式知道當前是哪個物件在呼叫它。當 呼叫delete this時,類物件的記憶體空間被釋放。在delete this之後進行的其他任何函式呼叫,只要不涉及到this指標的內容,都能夠正常執行。一旦涉及到this指標,如運算元據成員,呼叫虛函式等,就會出現不可預期的問題。

為什麼是不可預期的問題?delete this之後不是釋放了類物件的記憶體空間了麼,那麼這段記憶體應該已經還給系統,不再屬於這個程序。照這個邏輯來看,應該發生指標錯誤無訪問許可權之類的令系統崩潰的問題才對啊?這個問題牽涉到作業系統的記憶體管理策略。delete this釋放了類物件的記憶體空間,但是記憶體空間卻並不是馬上被**到系統中,可能是緩衝或者其他什麼原因,導致這段記憶體空間暫時並沒有被系統收回。此時這段記憶體是可以訪問的,你可以加上100,加上200,但是其中的值卻是不確定的。當你獲取資料成員,可能得到的是一串很長的未初始化的隨機數;訪問虛函式表,指標無效的可能性非常高,造成系統崩潰。

大致明白在成員函式中呼叫delete this會發生什麼之後,再來看看另乙個問題,如果在類的析構函式中呼叫delete this,會發生什麼?實驗告訴我們,會導致堆疊溢位。原因很簡單,delete的本質是「為將被釋放的記憶體呼叫乙個或多個析構函式,然後,釋放記憶體」 (來自effective c++)。顯然,delete this會去呼叫本物件的析構函式,而析構函式中又呼叫delete this,形成無限遞迴,造成堆疊溢位,系統崩潰

--------------------我是分介面--------------------

上面是某大牛的分析,而在實際的執行過程中使用delele this確實會直接出現錯誤。這是因為:在成員函式中呼叫delete this,首先會呼叫類的析構函式,this指標已刪除,會出現指標錯誤。

下面是在xcode中使用delete this出現的錯誤:

malloc: *** error for object 0xbffffa18: pointer being freed was not allocated

//注意0xbffffa18即為this的位址

*** set a breakpoint in malloc_error_break to debug

而在vs2010中使用delete this是直接導致 debug assertion failed!

具體的描述是:invalid null pointer

總結:在成員函式中呼叫delete this,會導致指標錯誤,而在析構函式中呼叫delete this,出導致死迴圈,造成堆疊溢位。

ps:this是類中成員函式具有的乙個附加的隱含形參,即指向該類物件的乙個指標,它與呼叫成員函式的物件繫結在一起。同時1.在普通的非const成員函式中:

this的型別是乙個指向類型別的const指標,可以改變this指向的值,但是不能改變this所儲存的位址;2.在const成員函式中,this的型別是乙個指向const類型別物件的const指標,既不能改變this所指向的物件,也不能改變this所儲存的位址

。注意:

成員函式中不能定義this形參,而是由編譯器隱含地定義,但是可以在成員函式中顯示使用this形參,不過也不是必須這麼做。如果對類成員的引用沒有限定,編譯器會將這種引用處理成通過this指標的引用。

有一種情況下必須顯式使用this:當我們需要將乙個物件作為整體引用而不是引用物件的乙個成員時。

從const成員函式返回*this

:不能從const成員函式返回指向類物件的普通引用。const成員函式只能返回*this作為乙個const引用。

在類的成員函式中呼叫delete this

在類的成員函式中能不能呼叫delete this?答案是肯定的,能呼叫,而且很多老一點的庫都有這種 假設這個成員函式名字叫release,而delete this就在這個release方法中被呼叫,那麼這個物件在呼叫release方法後,還能進行其他操作,如呼叫該物件的其他方法麼?答案仍然是肯定的,...

類成員函式呼叫

大家都知道c 的虛函式前必須加virtual,但如果一連串的繼承下來,有的忘了加virtual會出現什麼情況呢?為了滿足我的好奇心,做了點實驗然後有了本文,僅僅是好玩,沒有啥實際意義。本文只給出vs2005的情況 首先,如果是單一類,沒加virtual的話那麼好辦,直接call a fun,非sta...

在類的成員函式中能不能呼叫delete this?

如圖 解析 1.在類的成員函式中能不能呼叫delete this?答案是肯定的,能呼叫,而且很多老一點的庫都有這種 假設這個成員函式名字叫release,而delete this就在這個release方法中被呼叫,那麼這個物件在呼叫release方法後,還能進行其他操作,如呼叫該物件的其他方法麼?答...