C++核心指导原则: 接口部分
C++ Core Guidelines 整理目录
I. Interfaces
I.1: Make interfaces explicit
- 翻译: 使接口明确.
- 原因: 明确的接口能够帮助开发者更容易地理解和使用代码, 减少误解和错误.
I.2: Avoid non-const
global variables
- 翻译: 避免非 const 全局变量.
- 原因: 全局变量可能会导致难以追踪的状态改变, 影响程序的可维护性和稳定性.
I.3: Avoid singletons
- 翻译: 避免单例模式.
- 原因: 单例模式可以导致隐藏的依赖关系, 增加测试难度, 并可能引起并发问题.
I.4: Make interfaces precisely and strongly typed
- 翻译: 让接口精确且强类型化.
- 原因: 强类型的接口可以帮助编译器捕捉更多错误, 提高代码的安全性和可靠性.
I.5: State preconditions (if any)
- 翻译: 声明前置条件(如果有的话).
- 原因: 清晰地定义函数或方法调用前需要满足的条件有助于防止非法操作和潜在的运行时错误.
I.6: Prefer Expects()
for expressing preconditions
- 翻译: 使用 Expects()表达前置条件.
- 原因: 提供了一种标准化的方式来声明和检查前置条件, 增加了代码的可读性和可维护性.
I.7: State postconditions
- 翻译: 声明后置条件.
- 原因: 后置条件描述了函数执行后的预期状态, 有助于确保函数正确实现了其功能. C++26 引入了
Contract
来做参数的输入检查, 以及返回值检查.
I.8: Prefer Ensures()
for expressing postconditions
- 翻译: 使用 Ensures()表达后置条件.
- 原因: 类似于 Expects(), Ensures()提供了一种结构化的方式声明后置条件, 增强了代码的可理解性.
I.9: If an interface is a template, document its parameters using concepts
- 翻译: 如果接口是一个模板, 使用概念文档化其参数.
- 原因: 概念(Concept)为模板参数提供了更清晰的约束和意图说明, 使得模板更加易于理解和使用. 关于 Concept 请参考: C++20 Concepts 简介
I.10: Use exceptions to signal a failure to perform a required task
- 翻译: 使用异常来表示无法完成所需任务.(这个话题的争议比较多, 请自行甄别).
- 原因: 异常处理机制提供了一种有效的途径来管理错误情况, 而不必在每个函数返回值中都包含错误码.
I.11: Never transfer ownership by a raw pointer (T*
) or reference (T&
)
- 翻译: 不要通过原始指针(
T*
)或引用(T&
)转移所有权. - 原因: 使用智能指针或其他所有权管理工具可以避免资源泄露和其他与内存管理相关的问题.
I.12: Declare a pointer that must not be null as not_null
- 翻译: 将必须不为空的指针声明为
not_null
. - 原因: 这样可以提前捕获空指针引用错误, 提升程序的健壮性.
I.13: Do not pass an array as a single pointer
- 翻译: 不要把数组作为单一指针传递.
- 原因: 直接传递数组可能导致尺寸信息丢失, 使用标准库容器(
std::array
/std::vector
/std::span
)或智能指针更为安全和高效.
I.22: Avoid complex initialization of global objects
- 翻译: 避免全局对象的复杂初始化.
- 原因: 复杂的初始化过程可能会导致难以调试的问题, 尤其是在多线程环境中.
I.23: Keep the number of function arguments low
- 翻译: 函数参数数量保持低位.
- 原因: 参数过多会使函数调用变得复杂, 难以管理和记忆.
I.24: Avoid adjacent parameters that can be invoked by the same arguments in either order with different meaning
- 翻译: 避免相邻参数可以用相同的参数以不同顺序调用而具有不同的意义.
- 原因: 这种设计容易导致调用时出错, 应当重新设计接口以消除这种模糊性.
I.25: Prefer empty abstract classes as interfaces to class hierarchies
- 翻译: 优先使用空抽象类作为类层次结构的接口.
- 原因: 空抽象类提供了一个简单的接口定义方式, 便于实现和扩展.
I.26: If you want a cross-compiler ABI, use a C-style subset
- 翻译: 如果你需要跨编译器的应用二进制接口(ABI), 使用 C 风格子集.
- 原因: C 语言具有稳定的 ABI, 可以在不同的编译器之间提供兼容性.
I.27: For stable library ABI, consider the Pimpl idiom
- 翻译: 对于稳定的库 ABI, 考虑使用 Pimpl 惯用法.
- 原因: Pimpl 惯用法可以帮助隐藏实现细节, 从而保护 ABI 不受内部变化的影响.
I.30: Encapsulate rule violations
- 翻译: 封装规则违规.
- 原因: 当违反某些规则不可避免时, 将其封装起来可以限制其影响范围, 降低风险.
Tags: