【C++】18.其他工具与技术[深蓝学院C++第16章]
一.异常处理
1.1 非正常行为
处理程序在调用过程中的非正常行为,
传统处理方法:传返回值表示函数调用是否正常结束
C++中的处理方法:通过关键字try/catch/throw引入异常处理机制
1.2 异常触发时的系统行为——栈展开
抛出异常后续的代码不会被执行,退栈
局部对象会按照构造相反的顺序自动销毁
系统尝试匹配相应的catch代码段,如果匹配到则执行,如果匹配不到则继续栈展开直到跳出main触发terminate结束进程运行
1.3 异常对象
系统会使用抛出的异常拷贝初始化一个临时对象,称为异常对象
异常对象会在栈展开过程中被保留,并最终传递给匹配的catch语句
1.4 try-catch语句块
一个 try 语句块后面可以跟一到多个 catch 语句块
每个 catch 语句块用于匹配一种类型的异常对象
catch 语句块的匹配按照从上到下进行
使用 catch(...) 匹配任意异常
在 catch 中调用 throw 继续抛出相同的异常
1.5 多个异常
在一个异常未处理完成时抛出新的异常会导致程序崩溃
不要在析构函数或 operator delete 函数重载版本中抛出异常
通常来说, catch 所接收的异常类型为引用类型
1.6 异常与构造、析构函数
使用 function-try-block保护初始化逻辑
在构造函数中抛出异常则已经构造的成员会被销毁,但类本身的析构函数不会被调用可能导致内存泄漏
1.7 标准异常

1.8 正确对待异常处理
不要滥用:异常的执行成本非常高
不要不用:对于真正的异常场景,异常处理是相对高效、简洁的处理方式
编写异常安全的代码
二.枚举与联合
2.1 枚举
一种取值受限的特殊类型
分为无作用域枚举与有作用域枚举( C++11 起)两种,enum class xx的声明方式是有作用域——为了避免冲突
枚举项缺省使用 0 初始化,依次递增,可以使用常量表达式来修改缺省值
可以为枚举指定底层类型,表明了枚举项的尺寸,enum Color : char,类似继承
无作用域枚举项可隐式转换为整数值;也可用 static_cast 在枚举项与整数值间转换
注意区分枚举的定义与声明
2.2 联合
将多个类型合并到一起以节省空间
通常与枚举一起使用
匿名联合,作为最近域的数据成员,如在结构体中定义联合,和结构体共享内存
在联合中包含非内建类型
三.嵌套类与局部类
3.1 嵌套类
在类中定义的类,具有自己的域,与外围类的域形成嵌套关系
嵌套类中的名称查找失败时会在外围类中继续查找
嵌套类与外围类单独拥有各自的成员
3.2 局部类
在函数内部定义的类
可以访问外围函数中定义的类型声明、静态对象与枚举
局部类可以定义成员函数,但成员函数的定义必须位于类内部
局部类不能定义静态数据成员
四.嵌套命名空间与匿名命名空间
4.1 嵌套命名空间
名字空间可以嵌套,形成嵌套域
注意同样的名字空间定义可以出现在程序多处,类似partial类,以向同一个名字空间中增加声明或定义
4.2 匿名名字空间
用于构造仅翻译单元可见的对象
可用static代替
可作为嵌套名字空间
五.位域与volatile关键字
5.1 位域
bool类型本来默认使用1个byte,如果声明为bool b1 : 1;则b1只占1个bit
显式表明对象尺寸,所占的位数
在结构体、类中使用
多个位域对象可能会被打包存取
声明了位域的对象无法取地址,因此不能使用指针或非常量引用进行绑定
尺寸通常会小于对象类型所对应的尺寸,否则取值受类型限制
5.2 volatile关键字
表明一个对象的可能会被当前程序以外的逻辑修改,这块内存可能被未知修改过,
每次都要从内存中读,缓存中数据不可信,如多线程时
相应对象的读写可能会加重程序负担注意慎重使用 —— 一些情况下可以用 atomic 代替

浙公网安备 33010602011771号