我应该何时以及如何使用异常处理?
我正在阅读有关异常处理的信息.我得到了一些关于什么是异常处理的信息,但我有几个问题:
I am reading about exception handling. I got some information about what exception handling is, but I have a few questions:
- 什么时候抛出异常?
- 我们可以使用返回值来指示错误,而不是抛出异常吗?
- 如果我通过 try-catch 块保护我的所有函数,它会不会降低性能?
- 何时使用异常处理?
- 我看到一个项目,该项目中的每个函数都包含一个 try-catch 块(即整个函数内的代码被 try-catch 块包围).这是一个好的做法吗?
- try-catch 和 __try __except 有什么区别?
推荐答案
这是我认为必须阅读的关于异常的非常全面的指南:
Here's quite comprehensive guide on exceptions that I think is a Must Read:
异常和错误处理 - C++ FAQ 或 C++ FAQ lite
Exceptions and error handling - C++ FAQ or C++ FAQ lite
作为一般经验法则,当您的程序可以识别阻止执行的外部问题时,抛出异常.如果您从服务器接收数据并且该数据无效,则抛出异常.磁盘空间不足?抛出异常.宇宙射线阻止你查询数据库?抛出异常.但是如果你从你自己的程序中得到一些无效的数据――不要抛出异常.如果您的问题来自您自己的错误代码,最好使用 ASSERT 来防范它.需要异常处理来识别程序无法处理的问题并将其告知用户,因为用户可以处理它们.但是您的程序中的错误不是用户可以处理的,因此程序崩溃会告诉我们不少于answer_to_life_and_universe_and_everything 的值不是 42!这永远不会发生!!!!11"异常.
As a general rule of thumb, throw an exception when your program can identify an external problem that prevents execution. If you receive data from the server and that data is invalid, throw an exception. Out of disk space? Throw an exception. Cosmic rays prevent you from querying the database? Throw an exception. But if you get some invalid data from inside your very own program - don't throw an exception. If your problem comes from your own bad code, it's better to use ASSERTs to guard against it. Exception handling is needed to identify problems that program cannot handle and tell them about the user, because user can handle them. But bugs in your program are not something the user can handle, so program crashing will tell not much less than "Value of answer_to_life_and_universe_and_everything is not 42! This should never happen!!!!11" exception.
捕捉一个异常,你可以用它做一些有用的事情,比如显示一个消息框.我更喜欢在以某种方式处理用户输入的函数中捕获一次异常.例如,用户按下按钮歼灭所有 hunams",在 annihilateAllHunamsClicked() 函数中,有一个 try...catch 块来表示我不能".尽管消灭 hunamkind 是一项复杂的操作,需要调用数十个函数,但只有一次 try...catch,因为对于用户而言,这是一个原子操作 - 单击按钮.每个函数中的异常检查都是多余的和丑陋的.
Catch an exception where you can do something useful with it, like, display a message box. I prefer to catch an exception once inside a function that somehow handles user input. For example, user presses button "Annihilate all hunams", and inside annihilateAllHunamsClicked() function there's a try...catch block to say "I can't". Even though annihilation of hunamkind is a complex operation that requires calling dozens and dozens of functions, there is only one try...catch, because for a user it's an atomic operation - one button click. Exception checks in every function are redundant and ugly.
另外,我不能推荐足够熟悉 RAII - 也就是说,确保所有初始化的数据都被自动销毁.这可以通过尽可能多地在堆栈上初始化来实现,当您需要在堆上初始化某些内容时,请使用某种智能指针.当抛出异常时,栈上初始化的所有东西都会被自动销毁.如果你使用 C 风格的哑指针,当抛出异常时你会面临内存泄漏的风险,因为没有人在异常时清理它们(当然,你可以使用 C 风格的指针作为你的类的成员,但要确保它们是在析构函数中处理).
Also, I can't recommend enough getting familiar with RAII - that is, to make sure that all data that is initialized is destroyed automatically. And that can be achieved by initializing as much as possible on stack, and when you need to initialize something on heap, use some kind of smart pointer. Everything initialized on the stack will be destroyed automatically when an exception is thrown. If you use C-style dumb pointers, you risk memory leak when an exception is thrown, because there is noone to clean them up upon exception (sure, you can use C-style pointers as members of your class, but make sure they are taken care of in destructor).
相关文章