[英]Why not call Destructor in C++?
我學習C++
概念。 我對構造函數和Destractor概念感到困惑。 退出程序時,編譯器將隱式調用析構函數。 但是在我的程序中,只有構造函數被調用。
#include <iostream>
using namespace std;
class A
{
int i;
public:
A()
{
cout<<"Constructor call"<<endl;
}
~A()
{
cout<<"Destructtor call"<<endl;
}
};
int main()
{
A *a = new A();
}
輸出:
Constructor call
因此,我有一個問題: 為什么析構函數在退出程序時不由編譯器隱式調用?
為什么析構函數在退出程序時不由編譯器隱式調用?
因為動態分配的對象不會自動銷毀。 這就是指定語言的方式。 跟蹤動態對象的破壞將需要運行時/內存開銷。
解決方案:不要泄漏動態分配的對象。
在C ++中,變量生存期有2種“類型”。 動態和自動的。
自動是這樣的:
void foo()
{
int i; // automatic storage
} // destroys i
在這里, i
離開作用域的那一刻(在foo
返回之后)將被破壞。 您可以通過使對象具有自動生存期來自己檢查此問題:
int main()
{
A a; // calls A's constructor and allocates memory.
} //calls A's destructor and frees the memory used.
您將看到構造函數和析構函數都將被調用。
第二種形式是動態分配的內存。 您可以使用new
來動態分配內存(就像您一樣),並使用delete
釋放該內存。 編譯器不會為您執行此操作。 這意味着,要破壞對象,您必須自己調用顯式delete
:
int main()
{
A* a = new A();
delete a; // calls A's destructor and frees the memory used.
}
如果您不調用delete
(如您的代碼),那么在程序離開main
指針的那一刻,指針a
被破壞了,現在我們有一塊內存,什么也無法到達,因此沒有人可以清理(使用delete
),這意味着您內存泄漏 。
但是,現代操作系統會在程序結束時自動回收該程序使用的所有內存,因此此時並沒有太大關系。 這確實意味着您的析構函數將不會像您剛剛看到的那樣被調用。
動態分配的內存使您可以執行一些巧妙的技巧,例如將對象的生存期控制到要使用delete
明確銷毀對象的程度。 使用new
和delete
的問題在於,忘記單個delete
非常容易,並且您的程序已經泄漏了內存,這就是為什么建議您遠離這種分配方式的原因。
如果出於某種原因您絕對需要動態生存期,請使用諸如std::unique_ptr
類的智能指針,它將在超出范圍時立即調用new
並delete
它。
您可以使用new
動態創建對象。 僅當使用delete
時,才會調用析構函數。
為了防止內存泄漏,您可以/應該使用諸如unique_ptr
類的智能指針。
無論如何,進程結束時,內存本身當然會被釋放。
在您的代碼中永遠不會調用析構函數,因為該對象永遠不會被破壞。
您動態分配A
對象,並且永遠不會取消分配它。 添加delete a;
進入main()
,您將看到析構函數在起作用:
int main()
{
A *a = new A();
delete a;
return 0;
}
在主函數中,創建一個指針變量,必須通過在主函數末尾delete a
來刪除它。
因為您有內存泄漏。 您動態地使用new
對象創建了一個對象,並承諾將管理該對象的生存期,並在以后使用delete
。 然后,您違反了諾言。
如果以通常的方式創建對象:
A a;
它將自動為您銷毀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.