基于C++核心指南(isocpp.github.io)的C++编码标准。在编写、审查或重构C++代码时使用,以强制实施现代、安全和惯用的实践。
源自 C++ 核心准则 的现代 C++(C++17/20/23)综合编码标准。强制执行类型安全、资源安全、不变性和清晰性。
enum 对比 enum class,原始指针对比智能指针)这些主题在整个准则中反复出现,并构成了基础:
const/constexpr 开始;可变性是例外| 规则 | 摘要 |
|---|---|
| P.1 | 直接在代码中表达想法 |
| P.3 | 表达意图 |
| P.4 | 理想情况下,程序应是静态类型安全的 |
| P.5 | 优先编译时检查而非运行时检查 |
| P.8 | 不要泄漏任何资源 |
| P.10 | 优先不可变数据而非可变数据 |
| I.1 | 使接口明确 |
| I.2 | 避免非 const 全局变量 |
| I.4 | 使接口精确且强类型化 |
| I.11 | 切勿通过原始指针或引用转移所有权 |
| I.23 | 保持函数参数数量少 |
// P.10 + I.4: Immutable, strongly typed interface
struct Temperature {
double kelvin;
};
Temperature boil(const Temperature& water);
// Weak interface: unclear ownership, unclear units
double boil(double* temp);
// Non-const global variable
int g_counter = 0; // I.2 violation
| 规则 | 摘要 |
|---|---|
| F.1 | 将有意义的操作打包为精心命名的函数 |
| F.2 | 函数应执行单一逻辑操作 |
| F.3 | 保持函数简短简单 |
| F.4 | 如果函数可能在编译时求值,则将其声明为 constexpr |
| F.6 | 如果你的函数绝不能抛出异常,则将其声明为 noexcept |
| F.8 | 优先纯函数 |
| F.16 | 对于 "输入" 参数,按值传递廉价可复制类型,其他类型通过 const& 传递 |
| F.20 | 对于 "输出" 值,优先返回值而非输出参数 |
| F.21 | 要返回多个 "输出" 值,优先返回结构体 |
| F.43 | 切勿返回指向局部对象的指针或引用 |
// F.16: Cheap types by value, others by const&
void print(int x); // cheap: by value
void analyze(const std::string& data); // expensive: by const&
void transform(std::string s); // sink: by value (will move)
// F.20 + F.21: Return values, not output parameters
struct ParseResult {
std::string token;
int position;
};
ParseResult parse(std::string_view input); // GOOD: return struct
// BAD: output parameters
void parse(std::string_view input,
std::string& token, int& pos); // avoid this
// F.4 + F.8: Pure, constexpr where possible
constexpr int factorial(int n) noexcept {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
static_assert(factorial(5) == 120);
T&& (F.45)va_arg / C 风格可变参数 (F.55)const T,这会抑制移动语义 (F.49)| 规则 | 摘要 |
|---|---|
| C.2 | 如果存在不变式,使用 class;如果数据成员独立变化,使用 struct |
| C.9 | 最小化成员的暴露 |
| C.20 | 如果你能避免定义默认操作,就这么做(零规则) |
| C.21 | 如果你定义或 =delete 任何拷贝/移动/析构函数,则处理所有(五规则) |
| C.35 | 基类析构函数:公开虚函数或受保护非虚函数 |
| C.41 | 构造函数应创建完全初始化的对象 |
| C.46 | 将单参数构造函数声明为 explicit |
| C.67 | 多态类应禁止公开拷贝/移动 |
| C.128 | 虚函数:精确指定 virtual、override 或 final 中的一个 |
// C.20: Let the compiler generate special members
struct Employee {
std::string name;
std::string department;
int id;
// No destructor, copy/move constructors, or assignment operators needed
};
// C.21: If you must manage a resource, define all five
class Buffer {