不应通过规范来学习C++
总原则
- 功能正确
- 可读
- 可维护
- 安全、可靠
- 可测试
- 高效、可移植
类和函数
保证静态类型安全
C++由于如下特性,不利于实现静态类型安全:
- Union类型
- 类型转换、退化
- 缩窄转换
- 范围错误
- void* 指针
应约束这些的使用,或用新特性如variant、span3来提升健壮性。
相比之下,Rust语言从设计之初实现了静态类型安全。
保证内存安全
内存完全由开发者控制,必须谨慎,保证内存安全,避免:
- 内存访问错误
越界、访问已释放的内存、解引用空指针、内存未初始化、指向局部变量的指针或引用被传递到作用域或其他线程 - 内存泄漏
申请的内存未及时释放
应通过智能指针、引用、RAII等特性来提升。
优先用编译器检查代码,在运行时检查前者不能覆盖的
如通过const避免变量被意外修改;用std::span保证char[]不越界,而不是在运行时检查长度;用static_assert4做编译时检查。
遵国际标准
禁用未定义行为5。
使用namespace
自定义命名空间可以有效减少命名冲突。不要用using namespace <>,这只是对历史代码的临时之计;禁用内联namespace6;通过匿名namespace或static封装不外露的类或函数。
代码风格
命名
- 英文单词、符合英文语法;禁用拼音。
- 慎用缩写,领域内通用的
- bool或函数名不用否定
- 函数、自定义类型推荐大驼峰风格(CameraConfig),类成员用小驼峰(cameraFocalLength)加下划线如
id_
,全局变量g_
加小驼峰如g_oneDeg2Rad
,局部变量、函数参数用小驼峰。
注释
代码命名本身应能说明意图(what),实现则描述how。
注释要惜字如金,该有的才有。
注释要与代码修改同步。
文件头的版权声明:
/*
* 版权所有(C)xx公司 代码文件创建年份(-最新修改年份)
*/
交付代码不应包含TODO、FIXME等注释。
格式
统一使用空格缩进,4 spaces,不要用tab,因为不同的编辑器显示tab的宽度可能有差异,十分影响阅读。
大括号换行建议K&R风格。
int Sum(const int n) {
int i = n;
int res = 0;
while(i>0) {
res += i;
i--;
}
return res;
}
行宽
建议<120,引导开发者缩短函数、变量命名,减少嵌套,提升可读性。换行时把操作符留在行尾,另起一行要缩进或对齐。
类
类成员按public、protected、private顺序,public等关键字与class对齐。
声明顺序:
- typedef、using、内置的类或结构体
- 静态常量
- 构造
- 赋值操作符
- 析构
- 其他函数
- 变量
构造函数初始化列表可一行,或另起一行缩进、以冒号开头。
函数
函数返回类型与函数名同行,函数参数可合理换行。
语句
- if、for、while、do while语句一定要加大括号,避免出错。
- switch语句中,case、default应相对switch缩进。
预处理
#
语句顶行,多层预处理嵌套,内部可适当缩进。
指针类型、引用类型
*
或&
既可靠近类型名,也可靠近变量名,建议统一靠近类型名。从对象或空间取成员的符号不需空格。
int a = 1;
int* p = &a;
int x = 0;
x++;
空格与空行
行尾不应有空格。二、三元操作符的两侧应有空格。