此處引用了某個人的文章的回複,我覺得回答得不錯,引用一下:
**在c++中,記憶體分為heap(堆區)--放置由new動態分配的記憶體,stack(棧區)--放置臨時(局部)變數,和靜態儲存區--放置靜態和全域變數;
**非局部靜態變數,在main()函數前由編譯器分配記憶體並初始化(構造),在main()結束後由編譯器將其佔用的記憶體釋放(析構),所以這部分記憶體只要程式不結束就不會釋放;
**局部變數在程式執行過程中由編譯器自動產生和銷毀;
**heap對象由new分配記憶體,必須由程式員通過delete釋放掉記憶體;
記憶體泄露一般都是發生在堆對象身上;
你舉的例子:
class B:public A
{
public:
B(int i):A(i)
{
}
}
建構函式並沒有動態分配記憶體,所以不管對對象的構造能不能成功,你都不必擔心記憶體泄露,編譯器幫你做了所以的工作 :)
**若在建構函式中有動態記憶體的分配,通過new,你也應該在解構函式中用delete將記憶體釋放;但若在建構函式中發生了異常(在new語句後),如果沒有異常處理函數,建構函式將退出,由於對象沒有被完全構造,對象的解構函式將不被調用,也就是delete語句沒有被執行,發生記憶體泄露;
**解決辦法:使用smart pointer(智能指標),已經寫了很多了,就不在羅嗦了,若還不太明白何以和我聯絡。
總結一下:
1不要在建構函式和解構函式拋出異常。
2如果在建構函式發生了異常,因為建構函式沒有完全初始化,所以發生異常的時候,是不會調用解構函式的。
3如果是類中的成員函數發生了異常,則會調用解構函式,代碼為證:
#include<iostream>
#include<string>
using namespace std;
class A{
public:
A(int* a){
p=new int;
*p=*a;
}
~A(){
cout<<"調用析構"<<endl;
delete p;
}
void show(){
int ac=3;
try{
throw ac;
}catch(int){
cout<<"拋出異常"<<endl;
}
}
private:
int *p;
};
int main(){
int x=100;
int *b=&x;
A a(b);
a.show();
return 0;
}