問題描述
在 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++ 中使用異常說明符嗎?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!