C++华丽的exception handling(异常处理)背后隐藏的阴暗面及其处理方法
作者: 来源: 发布时间:2012-2-1 8:32:23 点击:
看看下面这个简单例子:
#include <memory>
#include <iostream>
using namespace std;
class BaseClass
{
public:
BaseClass(){};
~BaseClass()
{
throw runtime_error("example runtime error.");
};
};
int main(int *argc , char **argv)
{
BaseClass *pBase = new BaseClass;
delete pBase;
return 0;
}
在VS2008下调用teminate时候还会调用abort,这个程序会非正常结束,如果在main函数中试图这样做:
int main(int *argc , char **argv)
{
BaseClass *pBase = new BaseClass;
try
{
delete pBase;
}
catch(runtime_error &err)
{
cout<<err.what()<<endl;
}
return 0;
}
结果会跟上面一样(非正常结束),因为delete是不会将任何异常传递到其外面的;一种比较折中的解决方法是,当destructor中存在异常抛出时,在destructor最后添加一个能捕获所有异常的catch处理块,catch处理块又什么工作都不做,如下:
~BaseClass()
{
try
{
throw runtime_error("error in destructor");
}
catch(...)
{
}
};
看起来是一种很坏很无奈的办法,但正如Scott Meyers在《effective c++》中所说:
“一般而言,将异常吞掉是个坏主意,因为它压制了"某些动作失败"的重要信息!然而有时候吞下异常也比负担"草率结束程序"或"不明确行为带来的风险好”。
后记
对于很多exception handling的概念性细节(比如何时使用引用类型的异常捕捉、异常捕获层次的类型转换等等)我没做任何阐述,可以去看看《C++ PRIMER》的第十七章,有着很想尽的讲解。。。 对于MS编译器对异常规范的不支持,我很难理解,因为G++编译器确实是支持的。之前在讨论C++的object布局时(点击这里)也曾感叹MS的编译器在优化方面没G++走得快,对于这些,或许是我运气不好,老是碰到MS不如G++的地方,也或许是我现在几乎不用G++编译器的而体会不到其不如MS编译器的地方的缘故吧。。。exception handling的确能为提高代码质量的改善作出或多说少的贡献,但华丽丽的外表下,因为用不好它而导致的程序的很多不明确(如teminate当前程序)和不正常(如资源泄露)行为也是令人比较头大的地方。貌似只有多熟用有技巧性的用是唯一能解决所有问题的方法了。。
#include <memory>
#include <iostream>
using namespace std;
class BaseClass
{
public:
BaseClass(){};
~BaseClass()
{
throw runtime_error("example runtime error.");
};
};
int main(int *argc , char **argv)
{
BaseClass *pBase = new BaseClass;
delete pBase;
return 0;
}
在VS2008下调用teminate时候还会调用abort,这个程序会非正常结束,如果在main函数中试图这样做:
int main(int *argc , char **argv)
{
BaseClass *pBase = new BaseClass;
try
{
delete pBase;
}
catch(runtime_error &err)
{
cout<<err.what()<<endl;
}
return 0;
}
结果会跟上面一样(非正常结束),因为delete是不会将任何异常传递到其外面的;一种比较折中的解决方法是,当destructor中存在异常抛出时,在destructor最后添加一个能捕获所有异常的catch处理块,catch处理块又什么工作都不做,如下:
~BaseClass()
{
try
{
throw runtime_error("error in destructor");
}
catch(...)
{
}
};
看起来是一种很坏很无奈的办法,但正如Scott Meyers在《effective c++》中所说:
“一般而言,将异常吞掉是个坏主意,因为它压制了"某些动作失败"的重要信息!然而有时候吞下异常也比负担"草率结束程序"或"不明确行为带来的风险好”。
后记
对于很多exception handling的概念性细节(比如何时使用引用类型的异常捕捉、异常捕获层次的类型转换等等)我没做任何阐述,可以去看看《C++ PRIMER》的第十七章,有着很想尽的讲解。。。 对于MS编译器对异常规范的不支持,我很难理解,因为G++编译器确实是支持的。之前在讨论C++的object布局时(点击这里)也曾感叹MS的编译器在优化方面没G++走得快,对于这些,或许是我运气不好,老是碰到MS不如G++的地方,也或许是我现在几乎不用G++编译器的而体会不到其不如MS编译器的地方的缘故吧。。。exception handling的确能为提高代码质量的改善作出或多说少的贡献,但华丽丽的外表下,因为用不好它而导致的程序的很多不明确(如teminate当前程序)和不正常(如资源泄露)行为也是令人比较头大的地方。貌似只有多熟用有技巧性的用是唯一能解决所有问题的方法了。。
上一篇:Forefront TMG卸载之后重新安装出错的几个故障 下一篇:
[收藏此文章]