析構函數有2種方式調用,一個是主動調用delete,另一個是根據RAII的規則,在對象的生命周期結束時自動析構。第一點沒什么好說的,就簡單講下第二點。
對象的生命周期不等於是程序的生命周期,一般我們所謂的生命周期就是一個作用域,當變量或者對象離開這個作用域時就會自動析構。一般一對{}就是一個作用域,舉個例子
int main() { for(int i=0; i<10; i++) { A a; } a//錯誤,脫離作用域 }
一般在函數里的對象,離開函數時才算離開作用域,即return發生時,才執行析構,所以main中定義的對象不是在你說的return 0;之前執行的。return是一個離開的標志,只有遇到了該標志,才會開始離開。for結束后,就無法使用a了,因為該對象的生命周期已結束。
全局對象的話,是在程序結束時才執行析構,即遇到main中的return時,任何程序都是從main開始,到main結束的。
如果是new的對象,即使離開了作用域也會一直存在,必須主動delete,否則只有在結束程序時才會執行析構。這里在說下內存泄漏,舉個例子
void fun() { A *a = new A(); } int main() { while(1) { fun(); } reutn0; }
當離開fun時,雖然離開了作用域,但用new動態開辟空間的對象是不會析構的,你可以觀察任務管理器,看到內存一直在上升。但你在其他地方卻無法使用a所開辟的空間,因為a這個指針是保存在棧上的,當離開作用域后就自動析構(或者說自動消失了),但它所在分配空間是分配在堆上的,只有主動析構或程序結束,才會釋放空間,也就是丟失了這塊空間的地址,無法操作這塊空間了。