Sei ceri c++ 笔记第3章(Expressions (EXP))
3-1不要对边缘效应的调用顺序产生依赖
Side effect:
- Modifying an object (如 ++,--)
- Calling a library IO function
- Accessing a volatile-qualified value
- 避免在同一行代码中调用多次变量且含++等可以导致其变化的表达式 func(i++,i)
- 防止调用函数的多个参数调用的变量间产生冲突
3-2 避免删除错误指针类型的数组
- 不要将指针运算用在多态上?
3-3 避免在unevaluated operands中采用边缘效应
Unevalueated operands:
- sizeof()
- typeid()
- noexcept()
- decltype()
- declval()
除外情况:
用于SFINAE的操作(如宏)
3-4 避免读取未初始化的数据
常见情况:
- 声明了变量,没赋初值
- 类中的成员,没在构造函数中初始化就使用
3-5 控制对象的生命周期
- 注意new和delete成对使用,注意delete完不要使用对象
- 注意调用函数内的声明变量生命周期结束后仍然被外部引用的情况
- 使用std::initialize_list<>时,注意其生命周期。作为类成员时不能被重新赋值,不要用它传递期望长期存储的值。
- 使用lambda时,防止传递引用类型作为std::function<>的形参
- 使用goto时注意生命周期
3-6 未指定const, valatile(cv)类型的对象,不要用作cv类型实现
- 指定了const的对象,不要转换为ncv再使用
- const成员函数改变成员变量,使用mutable关键字
- 用volatile,函数参数类型也要传volatile.
3-7 调用其它语言时,Language linkage 和 function's definition 要统一
3-8 不要使用或析构不完整的类
(如果类没有实现构造和析构函数,则是不完整的(nontrivial))
- 如果类不包含析构函数,不应作为其它类的指针成员
两种解决方案:
- 添加析构函数
- 使用shared_ptr
- 多态情况下,类成员以及,类成员函数使用基类
3-9 va_start()参数传递规则:
1. 第二个参数不能传递引用
2. 用double替代float
3. 传递的参数不应有nontrivial copy constructor,如std::string 应用char*代替
3-10 offsetof()参数规则
offsetof(type, member-designator) 会生成一个类型为 size_t 的整型常量,它是一个结构成员相对于结构开头的字节偏移量。成员是由 member-designator 给定的,结构的名称是在 type 中给定的。
1. 若对象包含函数,则为非标准class,不宜作为参数传递。
2. 注意static对象存在类之外。
3-11 不要传递非标准格式类作为执行边缘
标准格式类(standard-layout class):
1. 没有虚函数
2. 对于所有非静态成员有着同样的存取控制
3. 没有non-standard-layout的基类
4. 在最底层的派生类中没有非静态数据成员
5. 相同基类的非静态数据成员不能作为第一个成员
参考https://www.cnblogs.com/tingshuo/archive/2013/03/28/2986236.html
ABI(Application Binary Interface):
每个操作系统都会为运行在该系统下的应用程序提供应用程序二进制接口(Application Binary Interface,ABI)。ABI包含了应用程序在这个系统下运行时必须遵守的编程约定,不同的操作系统之间存在一定的边界。
注意调用库的函数时注意传递参数不要是nonstandard-layout class.
1.可以使用std::is_standard_layout<T> 来处理,以防止传递参数
2.extern "Fortran" 的情况,可以考虑强制将传入参数转换成standard-layout类再调用
3-12 lambda表达式不能存在于其引用对象
1. Lambda表达式不宜传递引用对象作为参数
3-13 不要在对象之外使用对象的bit值
1. 在进行memcpy时,考虑用memcmp,以及判断数据长度是否相等的方式
2. 用clear()代替memset(0),(memset遇到虚函数的情况会导致存储vtable)
3-14 不要依赖于moved-from对象的值
1. std::move用在适应的类型上
2. std::remove
https://www.cnblogs.com/jingyg/p/5613303.html
std::remove没有真正删除元素,而是返回了一个迭代器指向第一个“需要被删除”的元素,要配合std::erase一起使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)