問1:在類的成員函數中能不能調用delete this?
答:肯定的,能調用。
#include <iostream>#include <vector>using namespace std;class A{public: void f() { cout<<"delete this"<<endl; delete this; };};int main(){ { A a; }}問2:假設這個成員函數名字叫release,而delete this在release方法中調用,那么這個對象在調用release方法后,還能進行其他操作,如調用該對象的其他方法么?
答:仍然是肯定 的,調用release之后還能調用其他的方法。
但是有個前提:被調用的方法不涉及這個對象的數據成員和虛函數。
根本原因在于delete的功能和類對象的內存模型。當一個類對象聲明時,系統會為其分配內存空間。在類對象的內存空間中,只有數據成員和虛函數表指針,并不包含代碼內容,類的成員函數單獨放在代碼段中。在調用成員函數時,隱含傳遞一個this指針,讓成員函數知道是哪個對象在調用它。當調用delete this時,類對象的內存空間被釋放。在delete this之后進行的其他任何函數調用,只要不涉及到this指針的內容,都能夠正常運行。一旦涉及到this指針,如操作數據成員,調用虛函數等,就會出現不可預期的問題。
問3:為什么是不可預期的問題?delete this之后不是釋放了類對象的內存空間了么,那么這段內存應該已經還給系統,不再屬于這個進程。照這個邏輯來看,應該發生指針錯誤,無訪問權限之類的令系統崩潰的問題才對?。?/strong>
答:這個問題牽涉到操作系統的內存管理策略。delete this釋放了類對象的內存空間,但是內存空間卻并不是馬上被回收到系統中,可能是緩沖或者其他原因,導致這段內存空間暫時沒有被系統收回。此時這段內存是可以訪問的,但是當你獲取數據成員,可能得到的是一串很長的隨機數;訪問虛函數表時,指針無效的可能性非常高,很可能造成系統崩潰。
程序崩潰示例代碼
#include <iostream>#include <vector>using namespace std;class A{public: int a; A(int t = 0) { a = t; } void f1() { //使用了該對象的數據成員 cout<<a<<endl; } void f2() { //未使用該對象的數據成員 cout<<1<<endl; } virtual void f3() { cout<<a<<endl; } void release() { cout<<"delete this"<<endl; delete this; };};int main(){ { A a(10); a.f1(); a.f2(); a.f3(); a.release(); a.f1(); a.f2(); a.f3(); }}問4:如果在類的析構函數中調用delete this,會發生什么?
答:實驗告訴我們,會導致堆棧溢出。
delete的本質是將調用一個或多個析構函數,然后,釋放內存。顯然,delete this會去調用本對象的析構函數,而析構函數中又調用delete this,形成無限遞歸,造成堆棧溢出,系統崩潰。
#include <iostream>#include <vector>using namespace std;class A{public: ~ A() { cout<<"delete this"<<endl; delete this; };};int main(){ { A a; }}總結
在成員函數中調用delete this,會導致指針錯誤;
在析構函數中調用delete this,會造成棧溢出;
this是類中成員函數具有的一個附加的隱含形參,即指向該類對象的一個指針,它與調用成員函數的對象綁定在一起;
this的值不可變;
class A{public: void f(A a) { //this = &a; //error: lvalue required as left Operand of assignment }};?
請尊重作者的勞動,轉載請注明作者及原文地址(http://blog.csdn.net/lis_12/article/details/56049284).
如果覺得本文對您有幫助,請點擊‘頂’支持一下,您的支持是我寫作最大的動力,謝謝。
新聞熱點
疑難解答
圖片精選