C++编程技术之 异常处理(上) (三)

2014-11-23 22:19:43 ? 作者: ? 浏览: 12
throw 3;
}
~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 #"< if(objid==3)
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()"< ~Cat(){cout<<"~Cat()"< };

/*这些语句用来模拟内存不足的情况,可以不用鸟他
但可以看到这里的new中抛出了一个异常*/
class Dog
{
public:
void* operator new(size_t sz){
cout<<"allocating a Dog"< throw 47;
}
void operator delete(void* p){
cout<<"deallocating a Dog"< ::operator delete(p);
}
};

class UseResources
{
Cat* bp;
Dog* op;
public:
UseResources(int count=1){
cout<<"UseResources()"< bp=new Cat[count];
op=new Dog;
}
~UseResources(){
cout<<"~UseResources()"< delete [] bp;
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()"< ~Cat(){cout<<"~Cat()"< };

/*这些语句用来模拟内存不足的情况,可以不用鸟他
但可以看到这里的new中抛出了一个异常*/
class Dog
{
public:
void* operator new(size_t sz){
cout<<"allocating a Dog"< throw 47;
}
void operator delete(void* p){
cout<<"deallocating a Dog"< ::operator delete(p);
}
};

class UseResources
{
Cat* bp;
Dog* op;
public:
UseResources(int count=1){
cout<<"UseResources()"< bp=new Cat[count];
op=new Dog;
}
~UseResources(){
cout<<"~UseResources()"< delete [] bp;
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 return ptr[i];
throw RangeeError();
}
};

class Cat
{
public:
Cat(){cout<<"Cat()"< ~Cat(){cout<<"~Cat()"< void g(){}
};

class Dog
{
public:
void* operator new[](size_t sz){
cout<<"allocating a Dog"< throw 47;
}
void operator delete[](void* p){
cout<<"deallocating a Dog"< ::operator delete(p);
}
};

class UseResources
{
PWrap cats;
PWrap dog;
public:
UseResources(){
cout<<"UseResources()"< }
~UseResources(){
cout<<"~UseResources()"< }
void f(){cats[1].g();}
};

int main()
{
try{
UseResources ur;
}catch(int){
cout<<"inside handler"< }catch(...){
cout<<"inside catch"< }
return 0;
}

-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: