C++ 抛出新的 std::exception 与抛出 std::exception
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10948316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
throw new std::exception vs throw std::exception
提问by NoSenseEtAl
while looking at some code I stumbled onto:
在查看我偶然发现的一些代码时:
throw /*-->*/new std::exception ("//...
and I always thought that you don't need/you shouldn't use new
here.
What is the correct way, are both OK, if so is there any difference?
我一直认为你不需要/你不应该new
在这里使用。
什么是正确的方法,都可以,如果可以,有什么区别吗?
BTW from what I can see while "grepping" with PowerShell boost libs never use throw new
.
顺便说一句,从我在使用 PowerShell boost 库“grepping”时可以看到的内容来看,从来没有使用throw new
.
P.S. also I found some CLI code that uses throw gcnew
. Is that OK?
PS 我还发现了一些使用throw gcnew
. 这可以吗?
采纳答案by CB Bailey
The conventional way to throw and catch exceptions is to throw an exception object and to catch it by reference (usually const
reference). The C++ language requires the compiler to generate the appropriate code to construct the exception object and to properly clean it up at the appropriate time.
抛出和捕获异常的常规方法是抛出一个异常对象并通过引用(通常是const
引用)来捕获它。C++ 语言要求编译器生成适当的代码来构造异常对象并在适当的时候适当地清理它。
Throwing a pointer to a dynamically allocated object is never a good idea. Exceptions are supposed to enable you to write more robust code in the face of error conditions. If you throw an exception object in the conventional manner you can be sure that whether it is caught by a catch clause naming the correct type, by a catch (...)
, whether it is then re-thrown or not it will be destroyed correctly at the appropriate time. (The only exception being if it is never caught at all but this is a non-recoverable situation whichever way you look at it.)
抛出一个指向动态分配对象的指针从来都不是一个好主意。异常应该使您能够在面对错误情况时编写更健壮的代码。如果您以常规方式抛出异常对象,您可以确保它是否被命名正确类型的 catch 子句捕获catch (...)
,无论它是否被重新抛出,它都会在适当的时间被正确销毁。(唯一的例外是如果它根本没有被捕获,但无论您怎么看,这都是不可恢复的情况。)
If you throw a pointer to a dynamically allocated object you have to be sure that whatever the call stack looks like at the point you want to throw your exception there is a catch block that names the correct pointer type and has the appropriate delete
call. Your exception must never be caught by catch (...)
unless that block re-throws the exception which is then caught by another catch block that does deal correctly with the exception.
如果你抛出一个指向动态分配对象的指针,你必须确保无论调用堆栈在你想抛出异常的点上是什么样子,都有一个 catch 块,它命名了正确的指针类型并具有适当的delete
调用。您的异常绝不能被捕获,catch (...)
除非该块重新抛出异常,然后该异常被另一个正确处理异常的 catch 块捕获。
Effectively, this means you've taken the exception handling feature that should make it easier to write robust code and made it very hard to write code that is correct in all situations. This is leaving aside the issue that it will be almost impossible to act as library code for client code that won't be expecting this feature.
实际上,这意味着您已经采用了异常处理功能,该功能应该可以更轻松地编写健壮的代码,并使编写在所有情况下都正确的代码变得非常困难。这撇开了一个问题,即几乎不可能充当不期望此功能的客户端代码的库代码。
回答by Nawaz
No need to use new
when throwing exception.
new
抛出异常时无需使用。
Just write:
写就好了:
throw yourexception(yourmessage);
and catch as :
并捕获为:
catch(yourexception const & e)
{
//your code (probably logging related code)
}
Note that yourexception
should derive from std::exception
directly or indirectly.
请注意,yourexception
应该std::exception
直接或间接地派生自。
回答by Nawaz
Throwing new std::exception
is correct if the call site is expecting to catch a std::exception*
. But nobody will be expecting to catch a pointer to an exception. Even if you document that's what your function does and people read the documentation, they're still liable to forget and try to catch a reference to a std::exception
object instead.
投掷new std::exception
是正确的,如果调用点期待搭上了std::exception*
。但是没有人会期望捕获指向异常的指针。即使你记录了你的函数所做的事情并且人们阅读了文档,他们仍然容易忘记并尝试捕获对std::exception
对象的引用。
回答by user1202136
The C++ FAQ has a nice discussion on this:
C++ FAQ 对此有一个很好的讨论:
- https://isocpp.org/wiki/faq/exceptions#what-to-catch
- https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc
- https://isocpp.org/wiki/faq/exceptions#what-to-catch
- https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc
Basically "unless there's a good reason not to, catch by reference. Avoid catching by value, since that causes a copy to be made and the copy can have different behavior from what was thrown. Only under very special circumstances should you catch by pointer."
基本上“除非有充分的理由不这样做,否则按引用捕获。避免按值捕获,因为这会导致创建副本,并且副本的行为可能与抛出的行为不同。只有在非常特殊的情况下,您才应该通过指针捕获。 ”
回答by zkoza
Operator new cannot guarantee that it will never raise an exception. For this reason using it for throwing a "valid" (intended) exception would produce a code that cannot be guaranteed not to crash. Since there may be only one exception at a time, and your program tries to throw two before any of them can be caught, the best thing an implementation can do is to immediately abort your program, e.g. by calling std::terminate.
运算符 new 不能保证它永远不会引发异常。出于这个原因,使用它来抛出一个“有效”(预期的)异常会产生一个不能保证不会崩溃的代码。由于一次可能只有一个异常,并且您的程序试图在它们中的任何一个被捕获之前抛出两个异常,因此实现可以做的最好的事情是立即中止您的程序,例如通过调用 std::terminate。