析构函数里的异常处理


在 more effect C++的M11中指出:不要把异常抛出到析构函数之外。可我发现即使在析构函数内部处理异常也会遇到一些问题。
Session::~Session()
{
     try
     {
     logDestruction(this);
     endTransaction(); // 结束database transaction
     }
catch(...)
{}
}
如果logDestruction(this)函数里面抛出了异常,那么endTransaction()函数就得到不执行,这样或许可以根据logDestruction(this)函数和endTransaction()抛出的不同的异常类型在catch后分别处理。然而如果两个函数抛出同样类型的异常呢?

20 个解决方案

#1


Session::~Session()
{
     try
     {
     logDestruction(this);
     }
catch(...)
{}
     endTransaction(); // 结束database transaction
}
抛出异常后回不到抛出点了。

#2


endTransaction(); 函数如果再抛出的话,再写一个try catch?

#3


这样的话,如果析构函数里面调用十个函数,每个后面都要跟一个try catch?

#4


getlasterror

#5


呵呵,“不要把异常抛出到析构函数之外”并不说明“在析构函数内部处理异常就不会遇到问题”啊。楼主的疑问逻辑上不成立。

应该这样说:如果你发现某个类的析构函数总是难免抛出异常,那这个类该重新设计了。
宁可为这个类增加一个单独的“End”函数,而让析构函数变为空函数,也不要允许析构函数抛出异常。

#6


同意楼上,C++和Java在处理异常上面有些区别,Java里面可以往外这么抛异常,责任不断外抛,但是C++的感觉是能解决尽量自己解决,不要让外面的来管。

尽量少在C++里面用异常处理,而是尽可能是代码健壮,能够处理异常。当然这也需要一个平衡,因为处理错误的代码多了自然会影响到主逻辑代码的可读性,这个就要看经验了。

#7


到我的bolg里看《C与C++中的异常处理》吧。
愿你远离“异常”

#8


qhgary(Gary),你说“同意楼上”,但偶不完全同意你。:P
偶只同意“析构函数坚决不能抛出异常”,不同意“尽量少在C++里面用异常处理”。

#9


我发现Blog中也能学到很多东西的。呵呵。
同意steedhorse(晨星) ,必要的时候,就应该使用异常处理。

#10


只是“必要的时候”实在是太少了。最容易犯的错误就是“把错误当异常”而滥用异常。

#11


有几个正真需要用异常的地方?
malloc内存失败也用异常?没这个必要吧?

除非调用的和库会抛出异常,否则一律不用异常,嘿嘿
听说有的实现new还会抛出异常,还真没见过,嘿嘿

#12


如果对异常能不用就不用,会发现,其实C++可以没有异常,呵呵

#13


vector的at接口就是必须抛异常的接口。
dynamic_cast<T &>就是必须抛异常的接口。
也就是说:架构级/支撑级代码抛异常是常见的;用户级代码抛异常基本没必要。

#14


完全是对书的误解, 这里推荐使用智能指针.
唯一能够防止构造析构异常的, 就只有智能指针了.

楼上说的没错, 用户级的异常是很少见的, 出了内存问题.

#15


11th 的意思是:不要在 Destructor 中 throw 吧,这样会调用 terminate。

while stack unwinding is in progress for an exception, a destructor that throws another exception of its own that it does not also handle, causes the library terminate function is called. Ordinarily, terminate calls abort, forcing an abnormal exit from the entire program.

——refer C++ Primer

#16


如果析构出现异常,那么这个对象是释放了它的资源还是保留它的资源?
养成一个习惯,不要在析构中处理异常。steedhorse所说的应该调整设计是一个正确的做法。

#17


学习

#18


该回复被版主删除

#19


学习了,但是感觉lz的逻辑有些混乱..
1. 这个异常后跳出,找不到抛出点这和是不是在析构函数里没有任何关系.
2. 不要将异常抛出到析构函数外部,是因为这样一抛程序会崩溃,已经不是好不好的问题了.在标准里这是被禁止的.
3. "呵呵,“不要把异常抛出到析构函数之外”并不说明“在析构函数内部处理异常就不会遇到问题”啊。楼主的疑问逻辑上不成立。"

#20


malloc应该不会要异常了
现在有虚拟内存,永远都会分配到内存的
高质量C++中林锐写了个尝试将内存耗尽的程序..但是不行....

#21


我想是不是可以设计一个异常类,这个类中含有一个数据成员来决定是由logDestruction()函数还是由endTransaction()函数抛出的,然后在catch子句中判断呢?比如
class SomeException
{
public:
    SomeException( char ch );
    const char getkind()const { return ch; }
private:
    char ch;/*'l':由SomeException函数throw;'e'表示endTransaction函数throw的*/
    //...
};

void logDestruction()
{  //endTransaction同!

    //...
    if()
        throw SomeException('l');
    //...
}

Session::~Session()
{
     try
     {
         logDestruction(this);
         endTransaction(); // 结束database transaction
     }
     catch(SomeException &eobj)
     {
        if( eobj.getch() == 'l' )//由logDestruction()抛出的异常!
        {...}
        else  {...} //由endTransaction()抛出的异常!
     }
     catch(...)
     {}
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: