09 | exception:怎样才能用好异常?
该思维导图由 AI 生成,仅供参考
为什么要有异常?
- 深入了解
- 翻译
- 解释
- 总结
异常处理在C++中是非常重要的,它能够有效地处理程序运行时的特殊情况和严重错误。本文介绍了异常的基本概念和使用方式,包括异常的优势、C++中异常的使用方式、以及谨慎使用异常的观点。作者提出了三种使用异常的方式,强调了异常处理的成本和合理使用异常的重要性。此外,文章还介绍了C++标准中的noexcept指令,以及其在函数优化中的作用。总的来说,异常处理是C++中的一种重要的错误处理方式,合理使用异常可以使程序更加健壮和清晰。文章内容涵盖了异常的基本概念、使用方式和相关编译指令,对读者快速了解异常处理在C++中的重要性和使用方法提供了全面的概览。
《罗剑锋的 C++ 实战笔记》,新⼈⾸单¥59
全部留言(20)
- 最新
- 精选
- eletarior初识编程时,对异常处理的误解还是挺大的,可能是因为异常处理总是在教材的最后几页,觉得很难,然后就草草的误解了。之前有一份工作领导特意提到了正确地进行异常处理。后来认真学了下,接触到C++11后,才真正用起来。 异常的好处是不言自明的,加强程序的健壮性,避免大量if else形式的代码处理。坏处也是有的,比如某个函数是否抛异常,写的人不好确定,要关注具体逻辑;而用这个函数的人也不确定,可能还需要借助注释来说明这个函数会抛出了怎样的异常。而抛异常就要try 和catch处理,不处理程序就会崩溃,接口的“客户”可能会不乐意处理。 用异常时,我更多的将某个函数声明为 noexcept ,比如构造函数,而明确要抛异常的函数则声明为noexcept(false)。 而在代码里处处使用 try catch也是不明智的,需要根据具体的场景和业务来辨别。而有一点是需要特别注意的避免在catch里写真实的业务代码,不应该在里写改变整个程序的流程的代码。如果程序崩溃了,就让它崩溃吧。
作者回复: 非常好的经验,noexcept(false)这个显式声明对人很友好。
2020-05-2650 - 范闲异常是个很重要的东西。 涉及磁盘操作的最好使用异常+调用栈, 涉及业务逻辑的最好利用日志+调用栈, 涉及指针和内存分配的还是用日志+调用栈吧,这种coredump一般是内存泄露和内存不够引起的。
作者回复: 很不错的经验分享。
2020-05-27418 - Coder Wu个人感觉如果是封装功能库给其他人使用,可以考虑用异常,能方便传递错误信息给外部。如果是写业务逻辑的话,只是涉及到自身功能的错误,还是多用错误码的方式,并且配合日志,方便后续问题的跟踪。
作者回复: 我的观点和你恰恰相反,库最好还是用错误码的方式,不要把异常抛给外面处理,通俗点说就是eat your own dog food。 因为外界不了解库的工作机制,也不知道怎么处理异常才好,或者可能根本就不知道你会抛异常,这样的话库用起来就不是太安全。
2020-06-08417 - _smile滴水C老师我使用过python的try,能跳过数组越界错误,假设是用户代码,跳过并无大碍,避免直接崩溃,C++的try有跟python类似的用法吗?
作者回复: 虽然都是try,但两者的用法差距很大,不能直接照搬Python的用法。 C++里的try就是捕获异常,而在C++里数组越界不一定会引发异常,可能正常也可能直接crash,try只能捕获可控的异常,不是万能的。
2020-08-095 - 泰伦卢禁用异常典型的有google和美国国防部或者移动端,google是因为历史包袱,以前编译器对异常支持的不太好,所以都使用的错误码方式,近些年来沿用了之前得方式,不好两种错误处理方式都穿插到代码里,国防部是因为异常处理在catch异常时候程序运行速度受影响,移动端主要是因为异常处理的程序体积会大20-30%,而我们真的那么在意程序体积吗,我们普通人使用异常简直不能再香,只是用之前需要搞明白异常处理的各种注意事项
作者回复: 说的很好,异常是个好东西,但用不好也会有负面影响,需要了解它的特性后再结合自己的实际情况。
2020-05-264 - Geek_6a1d96底层功能库采用错误码,业务逻辑部分采用观察者模型抛异常,谁注册成观察者谁处理异常。不管是log,显示在ui,或者用数据库记录异常,重启重连操作,把他们注册成观察者,就能很方便的跨类,跨dll完成异常处理。
作者回复: great
2023-04-08归属地:北京3 - Stephen老师,"通过引入一个“中间层”来获得更多的可读性、安全性和灵活性"这句话中可读性和灵活性我可以理解,这是函数比较容易理解的特性,安全性怎么讲呢?请老师不惜赐教
作者回复: 因为有了一个中间层,也就加上了一层额外的控制,可以在这里定制抛出异常的逻辑,避免外界随意使用异常,比如统一抛出std::exception,而不是int、string,所以就会安全一些。
2020-10-122 - Eglinuxclass my_exception : public std::runtime_error { public: using this_type = my_exception; using super_type = std::runtime_error; public: my_exception(const char* msg): super_type(msg) {} my_exception() = default; ~my_exception() = default; private: int code = 0; }; 请问老师,这一句是什么语法?没看懂 my_exception(const char* msg): super_type(msg) {} 列表初始化吗?但是 super_type 不是成员变量呀
作者回复: 这个就是调用父类的构造函数,只是被改名成super_type了。
2020-06-2042 - xGdl两try-catch当函数体还是挺丑的吧
作者回复: 我觉得function-try的形式更清晰,可以自己写写试试。
2020-06-042 - reverse老师,在下说一下我在工作写代码三四年的时间内的一些感受 ,在下主要用的是nodejs java , node这块我觉得在es6之后可以结合promise async 函数 再配合try catch 写出简洁的的函数,java 要求的比较严格 ,它的编译器会强制要求你加上 try catch 尤其是对 io操作 来说 ,实际上node的io操作也需要如此,综上所述,偏向于业务逻辑的错误码需要自己合理的定义范围自己意义,涉及到硬件磁盘的需要强制性的捕获异常,设计大于编程,函数规格大于功能本身
作者回复: 很有价值的经验,错误处理是写程序时很重要的一块,但有的时候会不太注重,异常可以强制我们去处理错误。
2020-05-262