C++ 代码审查:检查什么以及如何提供反馈
代码审查是开发过程中必不可少的一环,尤其是在 C++ 中。这种语言提供了极大的自由度,但同时也伴随着责任。对于初学者来说,审查过程可能看起来令人生畏,但实际上它是一个强大的学习工具。在本文中,我们将详细分析在检查 C++ 代码时应注意什么,以及如何提供有用且不伤人的反馈。
1. 基本正确性与内存安全
在任何 C++ 代码中,首先要检查的是内存操作的正确性。C++ 没有垃圾回收机制,因此错误在这里是致命的。
检查什么:
- 内存泄漏:每个
new必须对应一个delete,每个new[]必须对应一个delete[]。最好使用智能指针(std::unique_ptr、std::shared_ptr)。 - 数组越界:使用
std::vector::at()代替[]运算符来捕获错误。 - 悬空指针:指向已释放内存的指针。
- 双重释放:对同一内存块重复执行
delete。
// 不好:手动管理内存int* arr = new int[100];// ... 工作 ...delete[] arr; // 容易忘记
// 好:使用 RAIIstd::vector<int> arr(100);// 内存将自动释放给审查者的建议:如果看到原始指针(int* ptr)或手动 new/delete——这是一个危险信号。建议使用 std::unique_ptr 或 STL 容器。
2. 标准库(STL)的使用
C++20/23 提供了丰富的标准库。初学者经常在可以使用现成解决方案的地方重复造轮子。
检查清单:
- 容器:使用
std::vector、std::array、std::map代替原始数组。 - 算法:使用
std::find、std::sort、std::copy代替手动循环。 - 字符串:使用
std::string代替char*。 - 流:使用
std::ifstream/std::ofstream代替 C 风格的fopen。
// 不好:手动查找bool found = false;for (int i = 0; i < vec.size(); ++i) { if (vec[i] == target) { found = true; break; }}
// 好:STL 算法bool found = std::find(vec.begin(), vec.end(), target) != vec.end();如何提供反馈:不要说“这是错的”,而是说:“逻辑很棒!STL 中有一个现成的函数 std::find,它可以做同样的事情,但更简洁、更安全。我们试试用它好吗?”
3. 代码风格、命名与常量性
代码的可读性是成功的一半。即使代码完美运行,如果无法维护,也是无用的。
需要注意什么:
- 命名:变量使用
snake_case(按 C++ 标准),类使用PascalCase。避免使用单个字母的名称(除了i用于计数器)。 - 常量性:不会改变的参数应该是
const。不修改对象的方法应该是const。 - 格式化:统一的缩进风格(通常是 4 个空格),运算符周围加空格。
- 魔法数字:将它们提取为常量(
constexpr int MAX_SIZE = 100;)。
// 不好:不可读int a = 5;for(int i=0;i<10;i