在类中调用delete this问题
轉載:https://blog.csdn.net/kuimzzs/article/details/81517451
很多時候,一些定義在類內的變量的生命周期在類外并不是很好的掌控,這樣就很容易造成內存泄漏得到問題
比如以下代碼:
class Test
{
public:
? ? void foo();
private:
? ? char *p;
};
?
void Test::foo()
{
? ? p = new char[50];
}
?
int main()
{
? ? Test t1;
? ? t1.foo();
? ? return 0;
}
這是一個很典型的例子,new到的堆上空間并沒有主動釋放,即使程序結束也不會自動清除(不過現在操作系統比較高級,會強制返還程序運行前的內存....但這并不是我們不養成良好習慣的理由)。
那么這時候,在析構函數中加入delete[] p就是個很好的習慣。
那么,正題來了,如果我們在成員函數中delete自己會怎么樣?
delete this
下面通過代碼來看:
class Test
{
public:
? ? Test(int _x);
? ? void foo();
? ? void show();
? ? void show(int);
private:
? ? int x;
};
?
Test::Test(int _x) :x(_x)
{
}
?
void Test::show()
{
? ? cout << “x =” << x << endl;
}
?
void Test::show(int)
{
? ? cout << "this is show int"<< endl;
}
?
void Test::foo()
{
? ? delete this;
}
?
int main()
{
? ? Test *t1 = new Test(5);
? ? cout << "before" << endl;
? ? t1->show();
? ? t1->foo();
? ? cout << "after" << endl;
? ? //t1->show();
? ? t1->show(1);
? ? system("pause");
? ? return 0;
}
首先編譯。結果是通過!證明在成員函數中調用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,形成無限遞歸,造成
堆棧溢出,系統崩潰。
?
總結
以上是生活随笔為你收集整理的在类中调用delete this问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: S7-200 CPU224XP 通讯连接
- 下一篇: 流媒体传输协议系列之--RTSP协议详解