C++例外; int或std :: exception?

Rus*_*shK 13 c++ exception

我正在编写一些需要进行错误报告的库函数.我想使用异常而不是返回值.

我编写了抛出异常的函数.

例如:

if(strm->atEnd()){
    // unexpected end of stream
    throw -2;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,这种方法可以吗?或者我应该抛出从std :: exception派生的异常?

以什么方式抛出std :: exception更好?(除了能够使用catch(std :: exception&e))

抛出异常不好的做法?(所有throw int值都记录在doxygen注释中)

我找不到任何理由为什么(在这种情况下)我应该抛出一个对象.

Joh*_*web 18

我会抛出异常std::exception.

throw std::runtime_error("unexpected end of stream")
Run Code Online (Sandbox Code Playgroud)

我发现这更容易catch,记录,等等.它还允许从代码中删除注释和幻数.

然后可以将此消息发送给最终用户,以使他们有希望解决问题.

用户和库消费者无法读取代码中的注释,他们不太可能知道"-2"的含义.


And*_*uel 9

特殊行为是例外.他们是你应该担心优化的最后一件事!

唐纳德克努特说:

我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源

此外,作为例外的对象可以携带关于错误的信息.

例如,您有一个例外,意味着无法读取文件.如果抛出一个对象异常,该对象可能带有文件名,这是你不能拥有的整数.

如果异常来源未知(堆栈深处)并且没有人捕获它,则如果异常是具有适当信息的对象,则更容易调试程序.


Dou*_* T. 7

我的问题是,这种方法可以吗?

想想可读性.岂不

throw CUnexpectedEndOfStream();
Run Code Online (Sandbox Code Playgroud)

比...更具可读性

throw -2
Run Code Online (Sandbox Code Playgroud)

并且在很多情况下,不会在调试器中看到抛出CUnexpectedEndOfStream的实例意味着TONS超过-2.更不用说CUnexpectedEndOfStream可以存储有关问题的大量有用信息,例如说无法读取的文件以及可能有关问题性质的更多信息.

或者我应该抛出从std :: exception派生的异常?

std::exception如果您选择组织其他例外,那么继承可能会有所帮助.它是客户端代码可以使用的方便基类.另外,根据异常,您可能希望使用std :: runtime_error.

抛出异常不好的做法?(所有throw int值都记录在doxygen注释中)

谁说这是不好的做法?抛出异常是处理异常情况的好方法.我抛出的大多数异常都是因为客户端代码可能已经阻止了它应该做的事情 - 我的代码用户违反了合同.但是还存在许多其他特殊的非正常情况,例如操作系统错误,磁盘填满等等.所有不属于程序的东西都会正常流动.更重要的是,由于它们不是程序正常流程的一部分,因此您无需担心性能问题.

作为一个例子,我曾经使用异常来触发某个消息解析失败.但是,我发现这些解析错误经常发生,我开始处理异常并修复问题输入和重新分析.过了一会儿,我意识到更可读的解决方案是直接在解析代码中修复问题,并停止将其视为特殊情况.所有解析决策的代码都被放回到一个地方,我没有像醉酒的水手那样抛出咒语.