Should I use an exception specifier in C++?(我应该在 C++ 中使用异常说明符吗?)
问题描述
在 C++ 中,您可以使用异常说明符指定函数可能会或可能不会引发异常.例如:
In C++, you can specify that a function may or may not throw an exception by using an exception specifier. For example:
void foo() throw(); // guaranteed not to throw an exception
void bar() throw(int); // may throw an exception of type int
void baz() throw(...); // may throw an exception of some unspecified type
我对实际使用它们持怀疑态度,原因如下:
I'm doubtful about actually using them because of the following:
- 编译器并没有真正以任何严格的方式强制执行异常说明符,因此好处并不大.理想情况下,您希望得到编译错误.
- 如果函数违反了异常说明符,我认为标准行为是终止程序.
- 在 VS.Net 中,它将 throw(X) 视为 throw(...),因此对标准的遵守不强.
您认为应该使用异常说明符吗?
请回答是"或否",并提供一些理由来证明您的回答是正确的.
Do you think exception specifiers should be used?
Please answer with "yes" or "no" and provide some reasons to justify your answer.
推荐答案
没有
以下是几个原因:
模板代码不可能写出异常规范,
Template code is impossible to write with exception specifications,
template<class T>
void f( T k )
{
T x( k );
x.x();
}
副本可能会抛出,参数传递可能会抛出,x() 可能会抛出一些未知的异常.
The copies might throw, the parameter passing might throw, and x() might throw some unknown exception.
异常规范倾向于禁止可扩展性.
Exception-specifications tend to prohibit extensibility.
virtual void open() throw( FileNotFound );
可能演变成
virtual void open() throw( FileNotFound, SocketNotReady, InterprocessObjectNotImplemented, HardwareUnresponsive );
你真的可以把它写成
throw( ... )
第一个是不可扩展的,第二个是野心勃勃的,第三个是你真正的意思,当你写虚函数时.
The first is not extensible, the second is overambitious and the third is really what you mean, when you write virtual functions.
旧代码
当您编写依赖于另一个库的代码时,您真的不知道当出现可怕的错误时它会做什么.
When you write code which relies on another library, you don't really know what it might do when something goes horribly wrong.
int lib_f();
void g() throw( k_too_small_exception )
{
int k = lib_f();
if( k < 0 ) throw k_too_small_exception();
}
g 将终止,当 lib_f() 抛出时.这(在大多数情况下)不是您真正想要的.std::terminate() 不应该被调用.让应用程序因未处理的异常而崩溃,您可以从中检索堆栈跟踪,总比静默/暴力死亡要好.
g will terminate, when lib_f() throws. This is (in most cases) not what you really want. std::terminate() should never be called. It is always better to let the application crash with an unhandled exception, from which you can retrieve a stack-trace, than to silently/violently die.
编写返回常见错误并在异常情况下抛出的代码.
Write code that returns common errors and throws on exceptional occasions.
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;
}
尽管如此,当您的库只是抛出您自己的异常时,您可以使用异常规范来说明您的意图.
Nevertheless, when your library just throws your own exceptions, you can use exception specifications to state your intent.
这篇关于我应该在 C++ 中使用异常说明符吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我应该在 C++ 中使用异常说明符吗?
基础教程推荐
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 这个宏可以转换成函数吗? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 常量变量在标题中不起作用 2021-01-01
