抛出新的std ::exception与抛出std ::exception

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

throw /*-->*/new std::exception ("//... 

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

顺便说一句,我可以看到,而与PowerShell提升库“擦除”永远不会使用throw new

PS还发现了一些使用throw gcnew CLI代码。 这可以吗?

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

抛出一个指向dynamic分配对象的指针永远不是一个好主意。 例外情况可以让你在出现错误的情况下编写更健壮的代码。 如果以传统的方式抛出一个exception对象,那么可以确定它是否被一个catch子句捕获,命名为正确的types, catch (...)是否被重新抛出,将被销毁正确的在适当的时候。 (唯一的例外是,如果它从来没有被发现,但这是一个不可回收的情况,无论你怎么看待它。)

如果你向一个dynamic分配的对象抛出一个指针,你必须确保无论调用堆栈在你想抛出exception的地方是什么样的,都有一个catch块来命名正确的指针types,并且有适当的delete调用。 你的exception绝不能被catch (...)捕获,除非该块重新抛出那个被捕获的exception是另一个catch块来处理exception。

实际上,这意味着您已经采用了exception处理function,可以更轻松地编写健壮的代码,并且很难在所有情况下编写正确的代码。 这就抛开了这个问题:几乎不可能作为客户端代码的库代码,而不会期待这个function。

抛出exception时无需使用new

写吧:

 throw yourexception(yourmessage); 

并捕捉为:

 catch(yourexception const & e) { //your code (probably logging related code) } 

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

抛出new std::exception是正确的,如果调用站点期望捕获一个std::exception* 。 但是没有人会期望捕获一个指向exception的指针。 即使你logging了你的函数所做的事情,并且人们阅读了文档,他们仍然很容易忘记,并试图捕获对std::exception对象的引用。

C ++常见问题解答有一个很好的讨论:

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

基本上“除非有一个好的理由,不要以引用为基础,避免被价值捕捉,因为这会造成副本的产生,复制的行为可能与被抛出的行为不同,只有在非常特殊的情况下才能通过指针捕获。 “