Appearance
好的,我来详细讲解 C++ 编码规范的最佳实践。我会综合 Google C++ Style Guide 和业界通用的最佳实践。
1. 命名规范
变量命名
cpp
// 普通变量:小写+下划线(snake_case)
int student_count;
string user_name;
// 类成员变量:尾部加下划线
class MyClass {
private:
int member_variable_;
string name_;
};
// 常量:k开头+大驼峰 或 全大写+下划线
const int kMaxSize = 100;
const double kPi = 3.14159;
// 或者
const int MAX_SIZE = 100;
// 全局变量:g开头(尽量避免使用)
int g_global_counter;函数命名
cpp
// 普通函数:小写+下划线 或 小驼峰
void calculate_sum();
void processData(); // 小驼峰也常用
// 类方法:通常用小驼峰或小写+下划线
class Student {
public:
void setName(string name); // 小驼峰
string getName() const;
// 或者
void set_name(string name); // 小写+下划线
string get_name() const;
};类型命名
cpp
// 类名、结构体、枚举:大驼峰(PascalCase)
class StudentManager {
// ...
};
struct Point {
int x, y;
};
enum Color {
RED,
GREEN,
BLUE
};
// 类型别名
using StringVector = vector<string>;
typedef long long ll;2. 代码布局与格式
缩进和空格
cpp
// 使用 2 或 4 个空格(统一即可,Google 用 2 个)
void function() {
if (condition) {
do_something();
}
}
// 运算符两边加空格
int sum = a + b;
for (int i = 0; i < n; i++) {
// ...
}
// 逗号后面加空格
function(arg1, arg2, arg3);
// 指针和引用:紧靠类型(Google 风格)
int* ptr;
string& ref;
// 或紧靠变量名(也很常见)
int *ptr;
string &ref;大括号风格
cpp
// K&R 风格(常用,Google 采用)
void function() {
if (condition) {
// ...
} else {
// ...
}
}
// Allman 风格(也很常见)
void function()
{
if (condition)
{
// ...
}
else
{
// ...
}
}
// 单行语句也建议加大括号(更安全)
if (condition) {
return;
}行长度
cpp
// 每行不超过 80-100 字符
// 长语句需要换行
int result = very_long_function_name(parameter1, parameter2,
parameter3, parameter4);
// 链式调用换行
student.setName("Alice")
.setAge(20)
.setGrade("A");3. 头文件规范
头文件保护
cpp
// header.h
#ifndef PROJECT_PATH_HEADER_H_
#define PROJECT_PATH_HEADER_H_
// 头文件内容
#endif // PROJECT_PATH_HEADER_H_
// 或使用 #pragma once(现代编译器都支持)
#pragma once头文件包含顺序
cpp
// 1. 相关的头文件
#include "my_class.h"
// 2. C 系统头文件
#include <sys/types.h>
// 3. C++ 标准库头文件
#include <iostream>
#include <vector>
#include <algorithm>
// 4. 第三方库头文件
#include <boost/shared_ptr.hpp>
// 5. 本项目其他头文件
#include "other_class.h"前向声明
cpp
// 尽可能使用前向声明减少依赖
class Student; // 前向声明
class Classroom {
private:
Student* student_; // 指针可以只用前向声明
};4. 类设计规范
访问控制
cpp
class MyClass {
public:
// 构造函数、析构函数
MyClass();
~MyClass();
// 公有方法
void publicMethod();
protected:
// 保护成员(供子类使用)
void protectedMethod();
private:
// 私有成员变量
int private_variable_;
// 私有方法
void privateMethod();
};构造函数与初始化列表
cpp
class Point {
private:
int x_;
int y_;
public:
// 使用初始化列表(更高效)
Point(int x, int y) : x_(x), y_(y) {
// 构造函数体
}
// 默认构造函数
Point() : x_(0), y_(0) {}
// C++11: 使用 = default
Point() = default;
// 禁用拷贝构造(如果需要)
Point(const Point&) = delete;
Point& operator=(const Point&) = delete;
};Rule of Three/Five
cpp
class Resource {
private:
int* data_;
public:
// 如果需要自定义析构函数,通常也需要自定义拷贝和赋值
// 析构函数
~Resource() {
delete[] data_;
}
// 拷贝构造函数
Resource(const Resource& other) {
data_ = new int[100];
copy(other.data_, other.data_ + 100, data_);
}
// 拷贝赋值运算符
Resource& operator=(const Resource& other) {
if (this != &other) {
delete[] data_;
data_ = new int[100];
copy(other.data_, other.data_ + 100, data_);
}
return *this;
}
// C++11: 移动构造函数
Resource(Resource&& other) noexcept : data_(other.data_) {
other.data_ = nullptr;
}
// C++11: 移动赋值运算符
Resource& operator=(Resource&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
other.data_ = nullptr;
}
return *this;
}
};5. 现代 C++ 最佳实践
使用智能指针
cpp
// 避免使用裸指针,使用智能指针
#include <memory>
// unique_ptr:独占所有权
unique_ptr<int> ptr1 = make_unique<int>(42);
// shared_ptr:共享所有权
shared_ptr<string> ptr2 = make_shared<string>("hello");
// 避免
int* raw_ptr = new int(42); // 容易忘记 delete使用 auto 关键字
cpp
// 让编译器推导类型(简化代码)
auto x = 10; // int
auto str = string("hello");
auto vec = vector<int>{1, 2, 3};
// 迭代器使用 auto
for (auto it = vec.begin(); it != vec.end(); ++it) {
// ...
}
// 范围 for 循环
for (const auto& item : vec) {
cout << item << endl;
}使用 nullptr
cpp
// 使用 nullptr 代替 NULL 或 0
int* ptr = nullptr; // 正确
// 避免
int* ptr = NULL; // 旧式
int* ptr = 0; // 旧式使用 constexpr 和 const
cpp
// constexpr:编译期常量
constexpr int kMaxSize = 100;
constexpr double square(double x) { return x * x; }
// const:运行时常量
const int size = calculate_size();
// const 引用(避免拷贝)
void process(const vector<int>& data) {
// ...
}
// const 成员函数
class Point {
public:
int getX() const { return x_; } // 不修改成员
private:
int x_;
};使用枚举类
cpp
// 强类型枚举(C++11)
enum class Color {
Red,
Green,
Blue
};
Color c = Color::Red; // 需要作用域限定
// 避免传统枚举(容易命名冲突)
enum OldColor {
RED,
GREEN,
BLUE
};6. 注释规范
cpp
// 文件头注释
/**
* @file student.h
* @brief 学生管理类定义
* @author Your Name
* @date 2025-10-28
*/
// 函数注释
/**
* @brief 计算两个数的和
* @param a 第一个加数
* @param b 第二个加数
* @return 两数之和
*/
int add(int a, int b) {
return a + b;
}
// 类注释
/**
* @class Student
* @brief 表示一个学生的类
*
* 包含学生的基本信息和操作方法
*/
class Student {
// ...
};
// 行内注释:解释为什么,而不是做什么
int count = 0; // 记录有效数据的数量
// 避免无意义的注释
int i = 0; // 初始化 i 为 0(废话)7. 错误处理
cpp
// 使用异常处理
try {
risky_operation();
} catch (const exception& e) {
cerr << "Error: " << e.what() << endl;
}
// 函数返回值检查
if (!file.open("data.txt")) {
cerr << "Failed to open file" << endl;
return -1;
}
// 使用 assert 进行调试断言
#include <cassert>
assert(index >= 0 && index < size);8. 性能相关
cpp
// 按引用传递大对象
void process(const vector<int>& data); // 好
void process(vector<int> data); // 坏(拷贝开销大)
// 使用移动语义
vector<int> create_vector() {
vector<int> result(1000);
return result; // 自动使用移动语义(C++11)
}
// 预分配容器空间
vector<int> vec;
vec.reserve(1000); // 避免多次重新分配
// 使用 emplace 代替 push
vector<pair<int, int>> vec;
vec.emplace_back(1, 2); // 直接构造
vec.push_back({1, 2}); // 构造临时对象再拷贝9. 竞赛编程模板改进建议
cpp
#include <bits/stdc++.h> // 竞赛可用,工程项目避免
using namespace std;
// 类型别名
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using vi = vector<int>;
// 常用宏(竞赛中可用)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
// 常量定义
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const int MOD = 1e9 + 7;
// 快速输入输出
inline void fastIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
int main() {
fastIO();
// 你的代码
return 0;
}总结
核心原则:
- 一致性最重要:团队统一风格比具体选择哪种风格更重要
- 可读性优先:代码是写给人看的
- 使用现代 C++ 特性:智能指针、auto、范围for、nullptr等
- RAII原则:资源获取即初始化
- const correctness:尽可能使用const
- 避免过早优化:先保证正确性,再考虑性能
推荐阅读:
- Google C++ Style Guide
- C++ Core Guidelines (by Bjarne Stroustrup)
- Effective C++ / Effective Modern C++ (by Scott Meyers)