我在查看一些代码时偶然发现:
throw /*-->*/new std::exception ("//...
而我始终认为在这里不需要/不应该使用new
。
正确的方法是什么,两者都可以吗?如果可以,是否有任何区别?
BTW,从我用 PowerShell 进行 "grep" 的结果来看,boost 库从不使用throw new
。
P.S.我还发现一些 CLI 代码使用throw gcnew
。那样可以吗?
const
引用)捕获它。C++语言要求编译器生成适当的代码来构造异常对象并在适当的时间正确清理它。catch(...)
,无论它是否被重新抛出,它都将在适当的时候正确销毁。(唯一的例外是如果它根本没有被捕获,但无论如何这都是不可恢复的情况。)delete
调用的catch块。除非该块重新抛出异常并被另一个捕获块正确处理异常,否则您的异常绝不能被catch(...)
所捕获。在抛出异常时不需要使用new
。
只需写:
throw yourexception(yourmessage);
并捕获为:
catch(yourexception const & e)
{
//your code (probably logging related code)
}
请注意,yourexception
应该直接或间接地派生自 std::exception
。
new
?为什么要将你的异常从std::exception
派生出来? - Walterthrow std::exception;
无法工作?g++ 似乎无法编译它... - user645280std::exception
是一种类型,你不能抛出一个 类型,而是必须抛出一个 对象。所以语法应该是 throw std::exception();
这样就可以编译了。但它的好坏如何,则是完全不同的问题。 - Nawaz如果调用方期望捕获一个std::exception*
,那么抛出new std::exception
是正确的。但是没有人会期望捕获指向异常的指针。即使您记录了函数的行为并且人们阅读了文档,他们仍然可能会忘记并尝试捕获std::exception
对象的引用。
catch(...)
或者没有处理),那么抛出 new std::exception
才是正确的做法,否则将导致对象泄漏。简而言之,这几乎是不可能的。 - CB BaileyC++ FAQ中对此有一个很好的讨论:
基本上,“除非有充分的理由不这样做,否则要通过引用来捕获异常。避免通过值来捕获异常,因为这会导致复制,并且复制可能与被抛出的内容有不同的行为。只有在非常特殊的情况下才应该通过指针来捕获异常。”操作符new无法保证永远不会引发异常。因此,如果将其用于抛出“有效”(预期的)异常,将产生无法保证不崩溃的代码。由于一次只能有一个异常,并且在任何异常被捕获之前,您的程序尝试抛出两个异常,实现可以做的最好的事情就是立即终止您的程序,例如通过调用std::terminate。
throw gcnew
会很有用,例如当您希望托管代码捕获您的异常时。有人可以纠正我吗? - jpalecek