C++编码规范
1 总则
1.1 目的
统一 C++ 代码书写风格,提高代码可读性、可维护性,降低出错概率,便于团队阅读、调试和代码评审。
1.2 适用范围
本规范适用于所有 C++ 源代码(.cpp)、头文件(.h/.hpp)。
1.3 基本原则
- 可读性优先:代码首先是写给人看的,其次才是给编译器执行。
- 一致性原则:同一项目内风格保持统一。
- 简洁安全:避免晦涩技巧,优先保证代码安全,减少内存、类型相关 bug。
- 兼容标准:推荐使用 C++11 及以上标准,尽量不使用编译器特有非标准扩展。
2 命名规范
命名禁止使用拼音、无意义单字母(循环变量 i/j/k 除外)。
表格
| 类型 | 命名规则 | 示例 |
|---|---|---|
| 变量 | 小驼峰 / 下划线命名(项目统一即可,推荐下划线) | student_score、max_value |
| 常量 | 全大写,下划线分隔 | MAX_BUFFER_SIZE、PI |
| 类 / 结构体 | 大驼峰(帕斯卡命名) | StudentInfo、UserManager |
| 函数 | 小驼峰 或 下划线 | getScore()、calc_average() |
| 头文件保护宏 | 全大写,项目名_文件名_H | PROJECT_STUDENT_H |
| 命名空间 | 小写 | namespace utils {} |
| 枚举 | 枚举类型大驼峰,枚举值全大写 | enum Color {COLOR_RED, COLOR_BLUE}; |
禁止:
int a;(无意义变量,循环临时变量除外)、int 学生分数;(中文命名)
3 头文件规范
- 头文件必须使用头文件保护宏,禁止使用
#pragma once(部分编译器不支持,作业推荐宏)
#ifndef PROJECT_STUDENT_H
#define PROJECT_STUDENT_H
// 声明代码
#endif // PROJECT_STUDENT_H
- 头文件只放声明,实现放在.cpp 文件。
- 头文件包含顺序:本文件头文件 → C++ 标准库 → C 语言库 → 第三方库。
- 不要在头文件内定义全局变量,除非
inline。 - 尽量减少
#include,优先使用前置声明class A;。
4 格式与缩进
- 缩进:4 个空格,禁止 Tab(部分编辑器 Tab 宽度不一致)。
- 大括号:作业推荐K&R 风格(左大括号同行)
if (flag) {
doSomething();
} else {
return;
}
也可以选择 Allman 风格(大括号单独一行),整个项目只能选一种。
if (flag)
{
doSomething();
}
- 运算符两侧加空格:
a = b + c;,for (int i = 0; i < n; i++) - 逗号后面加空格:
func(a, b, c); - 每行代码不超过 80~100 字符,过长换行。
- 空行分隔逻辑块:函数之间空一行,逻辑段落空一行。
5 注释规范
注释要说明为什么这么写,而不是重复描述代码做了什么。
- 文件开头:文件功能、作者、日期。
/*
* 文件名:student.cpp
* 功能:学生信息管理
* 作者:XXX
* 日期:2026.10.01
*/
- 函数前:说明功能、参数含义、返回值。
/**
* @brief 计算平均值
* @param arr 输入数组
* @param len 数组长度
* @return 平均值
*/
double calcAverage(int arr[], int len);
- 单行注释:
// 注释内容,//后加空格。 - 废弃代码不要注释掉,直接删除。
- 不要大量注释,清晰的代码本身就是文档。
6 类型、变量与内存
- 变量就近定义,不要全部写在函数最开头。
//推荐
for (int i = 0; i < 10; i++) {
}
- 优先使用
const:只读参数、成员函数尽量加const。
double getValue() const;
void print(const std::string& str);
- 引用参数:输入参数优先
const &,避免拷贝开销。 - 指针:使用裸指针时明确所有权;C++11 及以上优先智能指针
std::unique_ptr、std::shared_ptr。 - 禁止内存泄漏:
new与delete配对,数组用new[]/delete[]。 - 不要使用魔术数字,用常量代替。
//不推荐
if (score > 60) {}
//推荐
const int PASS_SCORE = 60;
if (score > PASS_SCORE) {}
7 类与面向对象
- 访问权限顺序:
public→protected→private。 - 成员变量命名:可加前缀
m_区分局部变量,如m_name。 - 构造函数:优先初始化列表。
Student::Student(std::string name) : m_name(name) {}
- 禁止隐式类型转换,单参数构造函数加
explicit。 - 基类析构函数写
virtual,防止内存泄漏。
class Base {
public:
virtual ~Base() = default;
};
- 封装原则:成员变量尽量私有,通过 get/set 访问。
8 函数规范
- 函数功能单一,一个函数只做一件事。
- 函数长度不宜过长,尽量控制在 50 行以内。
- 参数个数不宜过多,建议不超过 5 个;过多可封装成结构体。
- 返回值清晰,避免用异常代替正常业务返回码(根据场景选择)。
9 语句与控制流
if/for/while即使只有一行代码,也要加大括号,防止后续修改引入 bug。
//不推荐
if (ok)
return;
//推荐
if (ok) {
return;
}
- 不要写多层深度嵌套(嵌套尽量≤4 层),嵌套太深拆分成函数。
- switch 语句:每个 case 都加 break;需要穿透 case 要写注释说明。
- goto:尽量禁止使用,仅在极少数资源清理场景允许。
10 标准库与语言特性
- 优先使用 STL 容器:
std::vector代替动态数组;std::string代替 char * 字符串。 - 禁止滥用宏:宏只用于头文件保护,常量优先用
constexpr。
constexpr int MAX_NUM = 100; //推荐
#define MAX_NUM 100 //不推荐
- C++11 推荐使用
auto简化类型书写,但不要滥用导致可读性下降。 - 不要使用
using namespace std;在头文件中;cpp 文件可酌情使用。
11 错误与异常处理
- 输入参数做合法性检查,防止越界、空指针访问。
- 数组访问前判断下标范围。
- 异常:大型项目使用异常;小型课程程序可以使用返回值判断错误。
12 禁止事项
- 不使用中文变量名、中文宏名。
- 不使用全局变量泛滥。
- 不随意强制类型转换
reinterpret_cast。 - 不返回局部变量的引用 / 指针。
- 不忽略函数返回值。
13 示例代码
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
class Student {
public:
explicit Student(const std::string& name, int score);
std::string getName() const;
int getScore() const;
void setScore(int score);
private:
std::string m_name;
int m_score;
};
#endif // STUDENT_H
#include "student.h"
Student::Student(const std::string& name, int score) : m_name(name), m_score(score) {
}
std::string Student::getName() const {
return m_name;
}
int Student::getScore() const {
return m_score;
}
void Student::setScore(int score) {
if (score >= 0 && score <= 100) {
m_score = score;
}
}
浙公网安备 33010602011771号