Appearance
C++ 编码规范的个人实践。综合了 Google C++ Style Guide 、业界通用的部分最佳实践以及个人特色。
1. 命名规范
变量命名
cpp
// 普通变量:小写+下划线(snake_case)
int student_count;
string user_name;
// 类成员变量:尾部加下划线 (Google C++ style)
class MyClass {
private:
int member_variable_;
string name_;
};
// 常量:全大写+下划线
const int MAX_SIZE = 100;函数命名
cpp
// 普通函数:小写+下划线
void calculate_sum();
// 类方法:小写+下划线
class Student {
public:
void set_name(string name); // 小写+下划线
string get_name() const;
};类型命名
cpp
// 类名、结构体、枚举:大驼峰(PascalCase)
class StudentManager {
// ...
};
struct Point {
int x, y;
};
enum Color {
RED,
GREEN,
BLUE
};
// 类型别名用using
using StringVector = vector<string>;2. 代码布局与格式
缩进和空格
cpp
// 使用 4 个空格
void function() {
if (condition) {
do_something();
}
}
// 运算符两边加空格
int sum = a + b;
for (int i = 0; i < n; i++) {
// ...
}
// 逗号后面加空格
function(arg1, arg2, arg3);
// 指针和引用:紧靠变量名
int *ptr;
string &ref;大括号风格
cpp
// K&R 风格
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
// 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++ 实践
不使用智能指针
使用 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 学生管理类定义
*/
// 函数注释
/**
* @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
// 按引用传递大对象
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}); // 构造临时对象再拷贝8. 竞赛编程模板
cpp
#include<bits/stdc++.h> // 竞赛可用,工程项目避免
using namespace std;
// 类型别名
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pli = pair<ll, int>;
using vi = vector<int>;
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
return 0;
}