抛出新的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 ++常见问题解答有一个很好的讨论:
- https://isocpp.org/wiki/faq/exceptions#what-to-catch
- https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc
基本上“除非有一个好的理由,不要以引用为基础,避免被价值捕捉,因为这会造成副本的产生,复制的行为可能与被抛出的行为不同,只有在非常特殊的情况下才能通过指针捕获。 “