为什么纯正C++代码不是吹毛求疵,而是尊重
如果你曾经打开过一个一年前“临时拼凑”的项目,却看不懂名为doStuff()的函数在做什么——那你一定明白我在说什么。纯正C++代码不仅仅是美学问题,更是对时间、精力和金钱的节省。C++是一门强大但也暗藏陷阱的语言:内存需要手动管理,模板可能催生庞杂的代码,运算符重载则像真正的魔法。如果没有纪律,代码很快就会变成“意大利面条”。
在本文中,我们将探讨如何写出易于阅读、维护和扩展的纯正C++代码。没有空话——只有实践、示例和经过验证的原则。
规则一:命名是成功的一半
变量、函数和类的名称应该回答“这是什么?”或“它做什么?”的问题。忘掉int x和void f()吧。使用有意义的名称。
反面示例
int d; // d是什么?距离?日期?笨蛋?void p() { // 打印?解析?哭泣? // ...}正面示例
int distanceInMeters;void printUserProfile() { // ...}建议:坚持使用一种风格。对于C++,标准做法是:变量和函数使用camelCase,类使用PascalCase。不要在同一项目中混用snake_case和camelCase——这会降低可读性。
规则二:函数应该短小且只做一件事
单一职责原则不仅适用于类,也适用于函数。理想的函数长度是5–20行。如果一个函数做了多件事——请拆分它。
反面示例
void processData(vector<int>& data) { // 排序 sort(data.begin(), data.end()); // 过滤 vector<int> filtered; for (int x : data) if (x > 0) filtered.push_back(x); // 输出 for (int x : filtered) cout << x << " ";}正面示例
vector<int> filterPositive(const vector<int>& data) { vector<int> result; for (int x : data) if (x > 0) result.push_back(x); return result;}
void printData(const vector<int>& data) { for (int x : data) cout << x << " ";}
void processData(vector<int>& data) { sort(data.begin(), data.end()); auto filtered = filterPositive(data); printData(filtered);}现在每个函数都可以单独复用和测试。纯正C++代码就是模块化。
规则三:避免魔数和魔字符串
那些从上下文中无法理解含义的数字和字符串是邪恶的。请将它们提取为常量。
反面示例
if (temperature > 100) { cout << "危险!";}正面示例
constexpr int MAX_SAFE_TEMPERATURE = 100;
if (temperature > MAX_SAFE_TEMPERATURE) { cout << "危险!";}现在,如果阈值发生变化,你只需在一个地方修改它,而不用在代码中搜索所有100。
规则四:注释不是烂代码的借口
最好的注释是那些不需要的注释,因为代码本身已经说明了一切。不要写“代码做了什么”——这显而易见。要写“为什么它这么做”。
反面注释
// 将i增加1i++;正面注释
// 对POD类型使用前置递增——更快++i;对于未完成的部分,可以使用// TODO:,但不要滥用。理想的代码不需要解释。
规则五:使用RAII和智能指针
C++以手动内存管理著称,但在现代C++(C++11及更高版本)中,有强大的工具