C++ Core Guidelines 整理目录
常量和不可变性
Con.1: By default, make objects immutable
-
翻译: 默认情况下, 使对象不可变.
-
原因: 不可变对象有助于提高代码的安全性和可读性, 减少错误和并发问题.
-
示例:
for (const int i : c) cout << i << '\n'; // 只读的情况建议用 const for (int i : c) cout << i << '\n'; // BAD
-
例外:
- 如果一个变量的角色是返回值, 并且拷贝的代价比较大, 那么就不要加
const
修饰, 因为这会引起不必要的拷贝.std::vector<int> fun() { std::vector<int> result{}; /* 返回值不要加const */ return result; }
- 函数的入参如果是值(不是引用)通常来说很少会被修改, 也很少会被定义为
const
.void fun(const int i) { /*...*/ } // 通常而言没有必要设置为const
- 如果一个变量的角色是返回值, 并且拷贝的代价比较大, 那么就不要加
Con.2: By default, make member functions const
-
翻译: 默认情况下, 使成员函数为
const
. -
原因:
const
成员函数保证不会修改对象的状态, 有助于维护数据的一致性和安全性. -
示例:
class Point { int x, y; public: int getx() { return x; } // 应该加上 const // ... }; void f(const Point& pt) { int x = pt.getx(); // 错误, 因为常量对象不能调用非 `const` 成员函数 }
Con.3: By default, pass pointers and references to const
s
-
翻译: 默认情况下, 传递指向常量的指针和引用.
-
原因: 这样可以避免无意中修改数据, 确保数据的完整性和程序的稳定性.
-
示例:
void f(char* p); // 默认f是会修改*p的 void g(const char* p); // g不会修改*p
Con.4: Use const
to define objects with values that do not change after construction
- 翻译: 使用
const
定义在构造后值不改变的对象. - 原因:
const
对象明确表示其状态在构造后不会改变, 有助于提高代码的清晰度和可维护性. - 示例:
void f()
{
int x = 7; // 默认 x 是可变的
const int y = 9; // y 是常量, 不会被修改
for (;;) {
/* ... */
}
// ...
}
Con.5: Use constexpr
for values that can be computed at compile time
- 翻译: 对可以在编译时计算的值使用
constexpr
. - 原因:
constexpr
允许某些计算提前到编译阶段进行, 可能提升程序性能, 并且有助于优化编译器的代码生成.
constexpr double f(int x) { /* ... */ }
double x = f(2); // 运行时计算
const double y = f(2); // 运行时计算
constexpr double z = f(2); // 编译时计算