析構函數什麼時候被調用
析構函數在下邊3種狀況時被調用:ios
對象生命週期結束,被銷燬時;
主動調用delete ;
對象i是對象o的成員,o的析構函數被調用時,對象i的析構函數也被調用。
第一種狀況函數
#include <iostream>spa
using namespace std;指針
class A
{
public:
A()
{
cout << "constructing A" << endl;
}
~A()
{
cout << "destructing A" << endl;
}
private:
int a;
};對象
void main()
{
A a;
}
運行結果:生命週期
constructing A
destructing A
1
2
第二種狀況內存
若是是new的對象,即便離開了做用域也會一直存在,必須主動delete,不然只有在結束程序時纔會執行析構。這裏在說下內存泄漏,舉個例子作用域
#include <iostream>io
using namespace std;class
class A
{
public:
A()
{
cout << "constructing A" << endl;
}
~A()
{
cout << "destructing A" << endl;
}
private:
int a;
};
void fun()
{
A *a = new A();
}
int main()
{
while (1)
{
fun();
}
return 0;
}
當離開fun時,雖然離開了做用域,但用new動態開闢空間的對象是不會析構的,你能夠觀察任務管理器,看到內存一直在上升。但你在其餘地方確沒法使用a所開闢的空間,由於a這個指針是保存在棧上的,當離開做用域後就自動析構(或者說自動消失了),但它所在分配空間是分配在堆上的,只有主動析構或程序結束,纔會釋放空間,也就是丟失了這塊空間的地址,沒法操做這塊空間了 。
第三種狀況
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "constructing A" << endl;
}
~A()
{
cout << "destructing A" << endl;
}
private:
int a;
};
class C
{
public:
C()
{
cout << "constructing C" << endl;
}
~C()
{
cout << "destructing C" << endl;
}
private:
int c;
};
class B : public A
{
public:
B()
{
cout << "constructing B" << endl;
}
~B()
{
cout << "destructing B" << endl;
}
private:
int b;
C c;
};
void main()
{
B b;
}
運行結果:
constructing A
constructing C
constructing B
destructing B
destructing C
destructing A
B的析構函數調用以後,又調用了B的成員c的析構函數 。
若將上邊的代碼中的main()函數內容改爲
A* a = new B;
delete a;
咱們知道,這將不會調用class B的析構函數不會被調用,因此class C的析構函數也不會被調用。
運行結果:
constructing A
constructing C
constructing B
destructing A
若將class A中的析構函數聲明爲虛函數 ,這時class B的析構函數也會被調用,例如:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "constructing A" << endl;
}
virtual ~A()
{
cout << "destructing A" << endl;
}
private:
int a;
};
class C
{
public:
C()
{
cout << "constructing C" << endl;
}
~C()
{
cout << "destructing C" << endl;
}
private:
int c;
};
class B : public A
{
public:
B()
{
cout << "constructing B" << endl;
}
~B()
{
cout << "destructing B" << endl;
}
private:
int b;
C c;
};
void main()
{
A* a = new B;
delete a;
}
運行結果:
constructing A constructing C constructing B destructing B destructing C destructing A