抛出新的std :: exception vs throw std :: exception

NoS*_*tAl 105 c++ exception

看着一些代码,我偶然发现:

throw /*-->*/new std::exception ("//...
Run Code Online (Sandbox Code Playgroud)

我一直认为你不需要/你不应该new在这里使用.
什么是正确的方法,都可以,如果有的话有什么区别吗?

BTW从我所看到的同时"使用PowerShell提升库"的"grepping"永远不会使用throw new.

PS我也发现了一些使用的CLI代码throw gcnew.这可以吗?

CB *_*ley 86

抛出和捕获异常的传统方法是抛出异常对象并通过引用(通常是const引用)捕获它.C++语言要求编译器生成适当的代码来构造异常对象并在适当的时候正确地清理它.

抛出指向动态分配对象的指针绝不是一个好主意.异常应该使您能够在错误条件下编写更强大的代码.如果以传统的方式抛出一个异常对象,你可以肯定,不管它是由一个catch子句命名正确的类型,抓住一个catch (...),无论是再重新抛出与否将在适当的时候正确销毁.(唯一的例外是,如果它从未被捕获,但这是一种不可恢复的情况,无论你以何种方式看待它.)

如果你把一个指向一个动态分配的对象,你必须确保,无论调用堆栈看起来像你想扔你的异常点有一个catch块名称正确的指针类型,并具有相应的delete调用.catch (...)除非该块重新抛出异常,然后捕获的是另一个正确处理异常的catch块,否则永远不能捕获您的异常.

实际上,这意味着您已经采用了异常处理功能,这使得编写健壮的代码变得更加容易,并且很难编写在所有情况下都正确的代码.这就抛开了一个问题,即几乎不可能充当客户端代码的库代码,而这些代码不会期望这个功能.


Naw*_*waz 29

new抛出异常时无需使用.

写吧:

throw yourexception(yourmessage);
Run Code Online (Sandbox Code Playgroud)

并抓住:

catch(yourexception const & e)
{
      //your code (probably logging related code)
}
Run Code Online (Sandbox Code Playgroud)

请注意,yourexception应该std::exception直接或间接地派生.

  • 为什么?为什么不使用`new`?为什么从`std :: exception`派生出`yourexception`? (7认同)
  • @ebyrob:`std :: exception`是一个类型,你不能抛出*类型*,你要抛出一个*对象*.所以语法应该是这样的:`throw std :: exception();`那将编译.现在有多好,完全是一个不同的问题. (5认同)

小智 22

new std::exception如果呼叫站点期望捕获a,则投掷是正确的std::exception*.但没有人会期望抓住指向异常的指针.即使你记录了你的功能和人们阅读文档的内容,他们仍然会忘记并尝试捕获std::exception对象的引用.

  • 抛出`new std :: exception`只有在调用站点期望捕获指针并且期望接管分配异常的管理时才是正确的,并且永远不会出现任何你将调用函数的情况.没有显式捕获正确指针的东西(`catch(...)`或根本没有处理)否则会有一个对象泄漏.简而言之,这可以近似为"从不". (27认同)

use*_*136 7

C++ FAQ对此有一个很好的讨论:

  1. https://isocpp.org/wiki/faq/exceptions#what-to-catch
  2. https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc

基本上"除非有充分的理由不通过引用捕获.避免按值捕获,因为这会导致复制,并且副本可能与抛出的行为有不同的行为.只有在非常特殊的情况下才应该通过指针捕获. "

  • 像往常一样,常见问题解答措辞严厉.您可以按价值或参考来捕捉.指针恰好是一个值(通过值或引用捕获).请记住,类型`A`与类型`A*`不同,所以如果我执行`throw A()`我不能用`catch(A*e)`来捕获它,因为它是完全不同的类型. (2认同)