3 回答
TA贡献1796条经验 获得超4个赞
没有。
这里有几个例子说明为什么:
模板代码无法使用异常规范编写,
template<class T>
void f( T k )
{
T x( k );
x.x();
}
副本可能会抛出,参数传递可能会抛出,并且x()可能会抛出一些未知异常。
异常规范倾向于禁止可扩展性。
virtual void open() throw( FileNotFound );
可能演变成
virtual void open() throw( FileNotFound, SocketNotReady, InterprocessObjectNotImplemented, HardwareUnresponsive );
你真的可以写成
throw( ... )
第一个是不可扩展的,第二个是过于雄心勃勃的,第三个实际上是您在编写虚拟函数时的意思。
旧版代码
当您编写依赖于另一个库的代码时,您真的不知道当发生严重错误时它可能会做什么。
int lib_f();
void g() throw( k_too_small_exception )
{
int k = lib_f();
if( k < 0 ) throw k_too_small_exception();
}
glib_f()抛出时将终止。(在大多数情况下)这不是您真正想要的。std::terminate()永远不应该被调用。总是让应用程序因未处理的异常而崩溃(从中可以检索堆栈跟踪)总是比静默/剧烈地消亡更好。
编写返回常见错误并在特殊情况下抛出的代码。
Error e = open( "bla.txt" );
if( e == FileNotFound )
MessageUser( "File bla.txt not found" );
if( e == AccessDenied )
MessageUser( "Failed to open bla.txt, because we don't have read rights ..." );
if( e != Success )
MessageUser( "Failed due to some other error, error code = " + itoa( e ) );
try
{
std::vector<TObj> k( 1000 );
// ...
}
catch( const bad_alloc& b )
{
MessageUser( "out of memory, exiting process" );
throw;
}
但是,当您的库仅引发您自己的异常时,您可以使用异常规范说明您的意图。
TA贡献1829条经验 获得超13个赞
我认为除约定外(对于C ++),标准
例外说明符是在C ++标准中进行的一项实验,多数失败。
唯一的例外是,不抛出说明符很有用,但您还应该在内部添加适当的try catch块,以确保代码与说明符匹配。Herb Sutter在此页面上有一个页面。戈特82
另外,我认为值得描述例外保证。
这些基本上是有关对象的状态如何受到异常转义的方法的文档。不幸的是,它们没有被编译器强制执行或以其他方式提及。
提升和例外
例外保证
不保证:
在异常转义方法之后,无法保证对象的状态。
在这些情况下,不应再使用该对象。
基本保证:
在几乎所有情况下,这都应该是方法提供的最低保证。
这保证了对象的状态定义正确,并且仍然可以被一致地使用。
强有力的保证:(又名交易保证)
这保证了该方法将成功完成,
否则将引发异常并且对象状态不会更改。
无投掷保证:
该方法保证不允许异常传播到该方法之外。
所有破坏者都应作出此保证。
| 注意:如果在已传播异常的情况下异常逃逸了析构函数
| 该应用程序将终止
TA贡献1811条经验 获得超4个赞
异常规范不是C ++中非常有用的工具。但是,如果与std :: unexpected结合使用,则/ is /有很好的用途。
在某些项目中,我要做的是编写具有异常规范的代码,然后使用将抛出我自己设计的特殊异常的函数调用set_unexpected()。构造后,此异常获取回溯(以特定于平台的方式),并从std :: bad_exception派生(如果需要,可以传播该异常)。如果它像往常一样引起了一个terate()调用,则回溯将由what()打印(以及引起它的原始异常;不难发现),因此我获得了合同所在位置的信息。违反,例如引发了意外的库异常。
如果这样做,我将永远不允许传播库异常(std异常除外),并从std :: exception派生我的所有异常。如果库决定抛出,我将捕获并转换为自己的层次结构,从而使我能够始终控制代码。由于明显的原因,调用依赖函数的模板化函数应避免使用异常规范。但是无论如何,很少有带有库代码的模板化函数接口(很少有库确实以有用的方式使用模板)。
- 3 回答
- 0 关注
- 403 浏览
添加回答
举报