此处引用了某个人的帖子的回复,我觉得回答得不错,引用一下:
**在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;
}