做js链接的网站要加证书吗,wordpress手动上传图片,seo搜索优化软件,广州网站建设程序开发C初学者指南-3.自定义类型(第一部分)-异常 文章目录 C初学者指南-3.自定义类型(第一部分)-异常简介什么是异常#xff1f;第一个示例用途:报告违反规则的行为异常的替代方案标准库异常处理 问题和保证资源泄露使用 RAII 避免内存泄漏#xff01;析构函数#xff1a;不要让异…C初学者指南-3.自定义类型(第一部分)-异常 文章目录 C初学者指南-3.自定义类型(第一部分)-异常简介什么是异常第一个示例用途:报告违反规则的行为异常的替代方案标准库异常处理 问题和保证资源泄露使用 RAII 避免内存泄漏析构函数不要让异常逃脱异常保证无抛出异常保证noexcept (C11) 简介
什么是异常
可以在调用层次结构中向上抛出的对象。
抛出将控制权转移回当前函数的调用方它们可以通过try…catch块捕获/处理如果不处理异常会向上传播直到它们到达 main如果main中没有处理异常将会调用std::terminatestd::terminate 的默认行为是中止程序
第一个示例
异常的最初动机是报告构造函数未能正确初始化对象即未能建立所需的类不变量(构造函数没有可用于错误报告的返回类型)。
#include stdexcept // standard exception types
class Fraction {int numer_;int denom_;
public: explicit constexprFraction (int numerator, int denominator): numer_{numerator}, denom_{denominator}{if (denom_ 0) throw std::invalid_argument{denominator must not be zero};}…
};
int main () {try { int d 1;std::cin d;Fraction f {1,d}; …} catch (std::invalid_argument const e) {// deal with / report error herestd::cerr error: e.what() \n;}…
}运行上面代码
用途:报告违反规则的行为
前提条件违规
前提条件 关于输入的期望有效函数参数违规示例 越界容器索引/平方根为负数宽契约函数在使用其输入值之前执行前置条件检查 在性能关键的代码中如果传入的参数已经知道是有效的那么人们不想支付输入有效性检查的成本因此通常不会使用这些方法。
未能建立/保持不变量
公共成员函数无法设置有效的成员值内存不足向量vector增长失败
后置条件违规
后置条件 关于输出的期望值返回值违规函数未能产生有效的返回值或损坏全局状态例子 构造函数失败无法返回除以零的结果
异常的优点和缺点 优点1将错误处理代码与业务逻辑分离 优点2错误处理集中化在调用链的更高层 优点3现在当没有抛出异常时性能影响可以忽略不计 缺点1但是抛出异常 时通常会影响性能 缺点2由于额外的有效性检查而影响性能 缺点3容易产生资源/内存泄漏更多见下文
异常的替代方案
输入值无效违反前提条件
窄契约函数在传递参数之前确保参数有效使用可以排除无效值的参数类型如今这是首选以获得更好的性能
未能建立/保留不变量
错误状态/标志将对象设置为特殊的无效值/状态
无法返回有效值违反后置条件
通过单独的输出参数引用或指针返回错误代码返回特殊的无效值使用特殊的词汇类型可以包含有效结果也可以什么都不包含就像C17的std::optional或Haskell的Maybe
标准库异常
异常是 C 标准库使用继承的少数地方之一 所有标准异常类型都是std::exception的子类型。
std::exception↑ logic_error| ↑ invalid_argument| ↑ domain_error| ↑ length_error| ↑ out_of_range| …↑ runtime_error↑ range_error↑ overflow_error↑ underflow_error…try {throw std::domain_error{Error Text};
}
catch (std::invalid_argument const e) {// 仅仅处理 invalid_argument异常…
}
// 捕捉其它所有异常
catch (std::exception const e) {std::cout e.what()// prints Error Text
}一些标准库容器提供了宽契约函数通过抛出异常来报告无效的输入值
std::vectorint v {0,1,2,3,4};
// 窄契约不检查以获取最大性能
int a v[6]; // 未定义行为
// 宽契约检查是否超范围
int b v.at(6); // throws std::out_of_range处理
重新抛出异常
try { // potentially throwing code
}
catch (std::exception const) { throw; // re-throw exception(s)
}捕获所有异常
try { // potentially throwing code
}
catch (...) { // handle failure
}集中异常处理
如果同样的异常类型在许多不同的地方被抛出可以避免代码重复。对于将异常转换为错误代码很有用
void handle_init_errors () {try { throw; // re-throw! } catch (err::device_unreachable const e) { … } catch (err::bad_connection const e) { … } catch (err::bad_protocol const e) { … }
}
void initialize_server (…) {try {…} catch (...) { handle_init_errors(); }
}
void initialize_clients (…) {try {…} catch (...) { handle_init_errors(); }
}问题和保证
资源泄露
几乎任何一段代码都可能抛出异常导致对 C 类型和库的设计产生重大影响。 如果与以下内容一起使用则可能是资源/内存泄漏的潜在来源
进行自己的内存管理的外部 C 库设计不佳不使用 RAII 进行自动资源管理的 C 库设计不佳在销毁时不清理资源的类型
示例由于 C 风格的资源处理而导致的泄漏 即两个单独的函数用于资源初始化连接和资源终止断开连接。
void add_to_database (database const db, std::string_view filename) {DBHandle h open_dabase_conncection(db); auto f open_file(filename);// 如果 open_file抛出异常则链接不会断开// do work…close_database_connection(h);// ↑ 如果open_file抛出了异常不会执行上面代码
}使用 RAII 避免内存泄漏
RAII 又是什么
构造函数资源获取析构函数资源释放/终结
如果抛出异常
局部作用域中的对象被销毁:被调用的析构函数使用 RAII正确释放资源
class DBConnector {DBHandle handle_;
public:explicitDBConnector (Database db): handle_{make_database_connection(db)} {}~DBConnector () { close_database_connection(handle_); }// 使connector不能复制:DBConnector (DBConnector const) delete;DBConnector operator (DBConnector const) delete;
};
void add_to_database (database const db, std::string_view filename) {DBConnector(db);auto f open_file(filename);// 如果 open_file 抛出异常 ⇒ 连接关闭// do work normally…
} // 连接关闭了!如果你需要使用一个比如来自C语言的库这个库采用独立的初始化和资源释放函数那么就编写一个RAII包装器。 通常如果无法控制引用的外部资源将包装器设为不可复制删除复制构造函数和复制赋值运算符也是有意义的。
析构函数不要让异常逃脱
… 否则资源可能会泄露
class E {
public:~E () { // throwing code ⇒ BAD!} …
};
class A {// some members:G g; F f; E e; D d; C c; B b;…
};如果对象e析构时抛出异常的话会导致 f 和 g 对象的析构函数没有被调用。
在析构函数中 捕获可能引发异常的代码
class MyType {
public:~MyType () { …try {// y throwing code…} catch ( /* … */ ) {// handle exceptions…} …}
};异常保证
如果引发异常 不能保证 任何 C 代码都应该默认做出这个假设除非它的文档另有说明
操作可能会失败资源可能泄露可能会破坏不变性 成员可能包含无效值部分执行失败的操作可能会导致副作用例如输出异常可能会向外传播
基本保正
不变量被保留没有资源泄漏所有成员都将包含有效值执行失败操作的部分可能会导致一些副作用例如值可能已写入文件
这是你最起码的目标
强保证提交或回滚语义
操作可能会失败但不会产生明显的副作用所有成员都保留其原值
内存分配容器应该提供这一保证即如果在增长过程中内存分配失败容器应保持有效和不变。
无抛出异常保证最强
保证操作成功外部看不到任何异常要么没有抛出异常要么在内部被捕获了使用 noexcept 关键字进行记录和强制执行
在高性能代码和资源受限的设备上首选此功能。
无抛出异常保证noexcept (C11)
void foo () noexcept { … }‘foo’ 承诺永远不会抛出异常或让任何异常逃逸如果一个异常从一个 noexcept 函数中逃逸了程序会被终止
好好想想你能不能遵守不抛出异常的承诺
noexcept是函数的接口的一部分甚至是自C17函数类型的一部分稍后将不抛出异常的函数更改为抛出异常的函数可能会破坏那些依赖不必处理异常的调用代码
有条件noexcept
A noexcept( expression )如果表示式为真则声明A不抛出异常A noexcept( noexcept( B ) )如果B为不抛出异常则声明A也不抛出异常
默认情况下为 noexcept(true)
都是隐式声明的特殊成员
默认构造函数析构函数复制构造函数 移动构造函数复制赋值运算符、移动赋值运算符继承的构造函数用户定义的析构函数
以上这些都是默认noexcept(true)
除非
他们需要调用 noexceptfalse 的函数明确的声明另有说明
附上原文地址 如果文章对您有用请随手点个赞谢谢^_^ 文章转载自: http://www.morning.rqqkc.cn.gov.cn.rqqkc.cn http://www.morning.rnzjc.cn.gov.cn.rnzjc.cn http://www.morning.qdsmile.cn.gov.cn.qdsmile.cn http://www.morning.jxfsm.cn.gov.cn.jxfsm.cn http://www.morning.mhybs.cn.gov.cn.mhybs.cn http://www.morning.tdfyj.cn.gov.cn.tdfyj.cn http://www.morning.xqxrm.cn.gov.cn.xqxrm.cn http://www.morning.cjqcx.cn.gov.cn.cjqcx.cn http://www.morning.fnpyk.cn.gov.cn.fnpyk.cn http://www.morning.xesrd.com.gov.cn.xesrd.com http://www.morning.rmkyb.cn.gov.cn.rmkyb.cn http://www.morning.wgqtj.cn.gov.cn.wgqtj.cn http://www.morning.psxfg.cn.gov.cn.psxfg.cn http://www.morning.fsnhz.cn.gov.cn.fsnhz.cn http://www.morning.sqxr.cn.gov.cn.sqxr.cn http://www.morning.ltdxq.cn.gov.cn.ltdxq.cn http://www.morning.plwfx.cn.gov.cn.plwfx.cn http://www.morning.fgqbx.cn.gov.cn.fgqbx.cn http://www.morning.ntdzjx.com.gov.cn.ntdzjx.com http://www.morning.jfnbh.cn.gov.cn.jfnbh.cn http://www.morning.kflbf.cn.gov.cn.kflbf.cn http://www.morning.lwgsk.cn.gov.cn.lwgsk.cn http://www.morning.kpcxj.cn.gov.cn.kpcxj.cn http://www.morning.dxqwm.cn.gov.cn.dxqwm.cn http://www.morning.krdmn.cn.gov.cn.krdmn.cn http://www.morning.wjwfj.cn.gov.cn.wjwfj.cn http://www.morning.pghfy.cn.gov.cn.pghfy.cn http://www.morning.ampingdu.com.gov.cn.ampingdu.com http://www.morning.mpxbl.cn.gov.cn.mpxbl.cn http://www.morning.frfpx.cn.gov.cn.frfpx.cn http://www.morning.tmbtm.cn.gov.cn.tmbtm.cn http://www.morning.rhsr.cn.gov.cn.rhsr.cn http://www.morning.cpktd.cn.gov.cn.cpktd.cn http://www.morning.yfstt.cn.gov.cn.yfstt.cn http://www.morning.ljzgf.cn.gov.cn.ljzgf.cn http://www.morning.xxzjb.cn.gov.cn.xxzjb.cn http://www.morning.lgsfb.cn.gov.cn.lgsfb.cn http://www.morning.kjlia.com.gov.cn.kjlia.com http://www.morning.lpcct.cn.gov.cn.lpcct.cn http://www.morning.tbjb.cn.gov.cn.tbjb.cn http://www.morning.xdpjs.cn.gov.cn.xdpjs.cn http://www.morning.nlglm.cn.gov.cn.nlglm.cn http://www.morning.nmqdk.cn.gov.cn.nmqdk.cn http://www.morning.coatingonline.com.cn.gov.cn.coatingonline.com.cn http://www.morning.rlhh.cn.gov.cn.rlhh.cn http://www.morning.xsqbx.cn.gov.cn.xsqbx.cn http://www.morning.nlbw.cn.gov.cn.nlbw.cn http://www.morning.zkdmk.cn.gov.cn.zkdmk.cn http://www.morning.wkmrl.cn.gov.cn.wkmrl.cn http://www.morning.qnywy.cn.gov.cn.qnywy.cn http://www.morning.pluimers.cn.gov.cn.pluimers.cn http://www.morning.spxsm.cn.gov.cn.spxsm.cn http://www.morning.chmcq.cn.gov.cn.chmcq.cn http://www.morning.xblrq.cn.gov.cn.xblrq.cn http://www.morning.pprxs.cn.gov.cn.pprxs.cn http://www.morning.rjkfj.cn.gov.cn.rjkfj.cn http://www.morning.jtfsd.cn.gov.cn.jtfsd.cn http://www.morning.jytrb.cn.gov.cn.jytrb.cn http://www.morning.tqrjj.cn.gov.cn.tqrjj.cn http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn http://www.morning.bwxph.cn.gov.cn.bwxph.cn http://www.morning.kbqws.cn.gov.cn.kbqws.cn http://www.morning.prprj.cn.gov.cn.prprj.cn http://www.morning.ysbrz.cn.gov.cn.ysbrz.cn http://www.morning.wgqtj.cn.gov.cn.wgqtj.cn http://www.morning.rqlzz.cn.gov.cn.rqlzz.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.lkkkf.cn.gov.cn.lkkkf.cn http://www.morning.dodoking.cn.gov.cn.dodoking.cn http://www.morning.ydrml.cn.gov.cn.ydrml.cn http://www.morning.tbjtm.cn.gov.cn.tbjtm.cn http://www.morning.ssjee.cn.gov.cn.ssjee.cn http://www.morning.kwqqs.cn.gov.cn.kwqqs.cn http://www.morning.cnvlog.cn.gov.cn.cnvlog.cn http://www.morning.lqqqh.cn.gov.cn.lqqqh.cn http://www.morning.yrjxr.cn.gov.cn.yrjxr.cn http://www.morning.jpgfx.cn.gov.cn.jpgfx.cn http://www.morning.cjmmn.cn.gov.cn.cjmmn.cn http://www.morning.yqkxr.cn.gov.cn.yqkxr.cn http://www.morning.sjqpm.cn.gov.cn.sjqpm.cn