在類中呼叫delete this問題

2021-08-22 12:14:06 字數 1857 閱讀 2345

很多時候,一些定義在類內的變數的生命週期在類外並不是很好的掌控,這樣就很容易造成記憶體洩漏得到問題

比如以下**:

class test

;void test::foo()

int main()

這是乙個很典型的例子,new到的堆上空間並沒有主動釋放,即使程式結束也不會自動清除(不過現在作業系統比較高階,會強制返還程式執行前的記憶體....但這並不是我們不養成良好習慣的理由)。

那麼這時候,在析構函式中加入delete p就是個很好的習慣。

那麼,正題來了,如果我們在成員函式中delete自己會怎麼樣?

delete this
下面通過**來看:

class test

;test::test(int _x) :x(_x)

void test::show()

void test::show(int)

void test::foo()

int main()

首先編譯。結果是通過!證明在成員函式中呼叫delete this 並沒有語法錯誤。

接下來執行:現在after後呼叫show(int)看delete this之後還能否呼叫成員函式。

結果如下圖:

可以看到,delete this之後,該物件的成員函式還能呼叫。

那麼,我們接下來就再次呼叫show()函式來看delete this 之後該物件中值釋放還在。

結果如下圖:

從結果來看,x已經變成隨機值,看來物件記憶體空間的確是被釋放了。

總結:

在類的成員函式可以呼叫delete this,並且delete this之後還可以呼叫該物件的其他成員,但是有個前提:被呼叫的方法不涉及

這個物件的資料成員和虛函式。

當乙個類物件宣告時,系統會為其分配記憶體空間。在類物件的記憶體空間中,只有資料成員和虛函式表指標,並不包含**內

容,類的成員函式單獨放在**段中。在呼叫成員函式時,隱含傳遞乙個this指標,讓成員函式知道當前是哪個物件在呼叫它。

當 呼叫delete this時,類物件的記憶體空間被釋放。在delete this之後進行的其他任何函式呼叫,只要不涉及到this指標的內容,都

能夠正常執行。一旦涉及到this指標,如運算元據成員,呼叫虛函式等,就會出現不可預期的問題,即上面出現的隨機值。

為什麼會出現這種情況?delete this之後不是釋放了類物件的記憶體空間了麼,那麼這段記憶體應該已經還給系統,不再屬於這個

程序。照這個邏輯來看,應該發生指標錯誤,無訪問許可權之類的令系統崩潰的問題才對啊?這個問題牽涉到作業系統的記憶體管理

策略。delete this釋放了類物件的記憶體空間,但是記憶體空間卻並不是馬上被**到系統中,可能是緩衝或者其他什麼原因,導致

這段記憶體空間暫時並沒有被系統收回。此時這段記憶體是可以訪問的,你可以加上100,加上200,但是其中的值卻是不確定的。當

你獲取資料成員,可能得到的是一串很長的未初始化的隨機數;訪問虛函式表,指標無效的可能性非常高,造成系統崩潰。

而若是下析構函式中呢?delete this會去呼叫本物件的析構函式,而析構函式中又呼叫delete this,形成無限遞迴,造成

堆疊溢位,系統崩潰。

上述總結參考了網上大神的一些言論,之前做的筆記,找不到是哪位了,,,不能標明,sorry

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

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

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

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

在成員函式中delete this指標

剛才在toplanguage上看到版主丟擲來的乙個問題,在成員函式中能不能delete this指標。我覺得是可以的,delete操作一般是先呼叫析構函式,再呼叫delete運算子。而且delete之後,該記憶體不會立刻被釋放,只是做個標記,告訴作業系統這塊記憶體可以被釋放掉了。至於系統什麼時候會釋...