C++核心指导原则: 其他杂项
C++ Core Guidelines 整理目录
CPL: C 风格编程
CPL.1: Prefer C++ to C
- 翻译: 优先选择 C++ 而不是 C.
- 原因: C++提供了更多的现代编程特性, 如类和对象, 模板, 异常处理等, 这些可以提高代码的安全性, 可维护性和复用性. 使用 C++还可以利用标准库提供的丰富功能, 减少手动编写底层代码的需求.
CPL.2: If you must use C, use the common subset of C and C++, and compile the C code as C++
- 翻译: 如果必须使用 C, 请使用 C 和 C++的公共子集, 并将 C 代码作为 C++编译.
- 原因: 这样可以确保代码在 C++环境中也能正常工作, 同时利用 C++的类型检查和其他安全特性. 这种方法有助于避免潜在的兼容性问题, 并且可以在需要时逐步迁移到更现代化的 C++代码.
CPL.3: If you must use C for interfaces, use C++ in the calling code using such interfaces
- 翻译: 如果必须使用 C 进行接口设计, 请在调用代码中使用 C++.
- 原因: 即使某些接口是用 C 语言定义的, 也可以在 C++代码中调用它们, 并利用 C++的功能来提高代码质量. 例如, 可以使用 RAII(资源获取即初始化)模式来管理资源, 或者使用智能指针来避免内存泄漏等问题.
A: 结构性考虑
A.1: Separate stable code from less stable code
- 翻译: 将稳定的代码与不稳定的代码分开.
- 原因: 通过将经过充分测试和验证的稳定代码与仍在开发或频繁变更的不稳定代码分离, 可以降低维护成本并提高系统的可维护性. 这种方法还便于进行独立的版本控制和发布管理.
A.2: Express potentially reusable parts as a library
- 翻译: 将可能重用的部分表达为库.
- 原因: 将可重用的代码封装成库有助于减少重复工作, 并促进代码的一致性和质量. 库的形式还可以方便地在多个项目之间共享和使用, 提升开发效率.
A.4: There should be no cycles among libraries
- 翻译: 库之间不应存在循环依赖.
- 原因: 循环依赖会导致编译复杂度增加, 影响构建时间和系统稳定性. 避免循环依赖可以使代码结构更加清晰, 便于维护和扩展. 通常可以通过重构代码, 引入接口层或使用依赖注入等方法来消除循环依赖.
Non-Rules and myths
NR.1: Don’t insist that all declarations should be at the top of a function
- 翻译: 不要强制要求所有声明都放在函数顶部.
- 原因: 现代 C++允许在需要的地方进行变量声明, 这有助于减少变量的作用域并提高代码的可读性和安全性. 将变量声明靠近其使用位置可以更好地理解代码逻辑.
NR.2: Don’t insist on having only a single return
-statement in a function
- 翻译: 不要强制要求函数中只有一个返回语句.
- 原因: 多个返回语句可以使代码更简洁和清晰, 特别是在有多个提前退出条件的情况下. 过度追求单一返回点可能会导致不必要的复杂性和嵌套结构.
NR.3: Don’t avoid exceptions
- 翻译: 不要避免使用异常.
- 原因: 异常处理机制是 C++标准的一部分, 用于处理错误情况非常有效. 合理使用异常可以提高代码的健壮性和可维护性, 避免复杂的错误检查代码.
NR.4: Don’t insist on placing each class definition in its own source file
- 翻译: 不要强制要求每个类定义都放在单独的源文件中.
- 原因: 将相关的类放在同一个文件中可以简化项目结构, 并提高代码的组织性和可维护性. 只有当类的功能独立且较大时, 才考虑将其放入单独的文件中.
NR.5: Don’t use two-phase initialization
- 翻译: 不要使用两阶段初始化.
- 原因: 两阶段初始化(即构造函数之外的额外初始化步骤)增加了代码的复杂性和出错的可能性. 应尽量通过构造函数完成对象的所有初始化工作, 确保对象在创建后立即可用.
NR.6: Don’t place all cleanup actions at the end of a function and goto exit
- 翻译: 不要将所有的清理操作放在函数末尾并通过
goto
跳转执行. - 原因: 使用
goto
进行清理操作会使代码难以理解和维护. 现代 C++提供了 RAII(资源获取即初始化)机制, 通过智能指针和局部对象管理资源, 可以在作用域结束时自动释放资源, 避免手动清理.
NR.7: Don’t make all data members protected
- 翻译: 不要将所有数据成员设为
protected
. - 原因: 将数据成员设为
protected
虽然比public
更安全, 但仍可能导致子类直接访问和修改父类的数据, 破坏封装性. 应尽量使用私有数据成员和受保护的接口方法来控制对数据的访问.
Tags: