}
~Trace(){
cout<<"destruction Trace #"<
};
int main()
{
try{
Trace n1;
Trace Array[5];
Trace n2;
}catch(int i){
cout<<"caught "< }
return 0;
}
#include
using namespace std;
class Trace
{
static int counter;
int objid;
public:
Trace(){
objid=counter++;
cout<<"construction Trace #"<
throw 3;
}
~Trace(){
cout<<"destruction Trace #"<
};
int main()
{
try{
Trace n1;
Trace Array[5];
Trace n2;
}catch(int i){
cout<<"caught "< }
return 0;
}
如果一个对象的构造函数则执行时发生异常,那么这个对象的析构函数就不会被调用,因此,如果在构造函数中分配了资源却产生异常,析构函数是不能释放这些资源的。例如常说的“悬挂”指针。
下面是一个例子:
[cpp]
#include
#include
using namespace std;
class Cat
{
public:
Cat(){cout<<"Cat()"<
/*这些语句用来模拟内存不足的情况,可以不用鸟他
但可以看到这里的new中抛出了一个异常*/
class Dog
{
public:
void* operator new(size_t sz){
cout<<"allocating a Dog"<
}
void operator delete(void* p){
cout<<"deallocating a Dog"<
}
};
class UseResources
{
Cat* bp;
Dog* op;
public:
UseResources(int count=1){
cout<<"UseResources()"<
op=new Dog;
}
~UseResources(){
cout<<"~UseResources()"<
delete op;
}
};
int main()
{
try{
UseResources ur(3);
}catch(int){
cout<<"inside handler"<
return 0;
}
#include
#include
using namespace std;
class Cat
{
public:
Cat(){cout<<"Cat()"<
/*这些语句用来模拟内存不足的情况,可以不用鸟他
但可以看到这里的new中抛出了一个异常*/
class Dog
{
public:
void* operator new(size_t sz){
cout<<"allocating a Dog"<
}
void operator delete(void* p){
cout<<"deallocating a Dog"<
}
};
class UseResources
{
Cat* bp;
Dog* op;
public:
UseResources(int count=1){
cout<<"UseResources()"<
op=new Dog;
}
~UseResources(){
cout<<"~UseResources()"<
delete op;
}
};
int main()
{
try{
UseResources ur(3);
}catch(int){
cout<<"inside handler"<
return 0;
}
Resources的析构函数没有被调用,这是因为在构造函数的时候抛出了异常,这样,创建的Cat对象也无法被析构。
为了防止资源泄露,需要用以下方法防止不成熟的资源分配方式:
1、在构造函数中捕获异常,用于释放资源
2、在构造函数中分配资源,在析构函数中释放资源
这样使得资源的每一次分配都具有原子性,称为资源获得式初始化,使得对象对资源的控制的时间与对象的生命周期相等,下面对上述例子作一些修改:
[cpp]
#include
#include
using namespace std;
template
class PWrap
{
T* ptr;
public:
class RangeeError{};
PWrap(){
ptr=new T[sz];
cout<<"Pwrap constractor"<
~PWrap(){
delete[] ptr;
cout<<"PWrap deconstracor"<
T& operator[](int i) throw(RangeeError){
if(i>=0&&i
throw RangeeError();
}
};
class Cat
{
public:
Cat(){cout<<"Cat()"<
};
class Dog
{
public:
void* operator new[](size_t sz){
cout<<"allocating a Dog"<
}
void operator delete[](void* p){
cout<<"deallocating a Dog"<
}
};
class UseResources
{
PWrap
PWrap
public:
UseResources(){
cout<<"UseResources()"<
~UseResources(){
cout<<"~UseResources()"<
void f(){cats[1].g();}
};
int main()
{
try{
UseResources ur;
}catch(int){
cout<<"inside handler"<
cout<<"inside catch"<
return 0;
}