个人C++编程规范总结


C++707 阅0 评

个人进行C++开发时会遵守的规范。参考了Google C++ Style Guide.

1. 头文件

1.1 #define保护

所有头文件都使用#define来保护,防止头文件被重复包含。

#ifndef <PROJECT>_<PATH>_<FILE>_H_
#define <PROJECT>_<PATH>_<FILE>_H_

#endif //<PROJECT>_<PATH>_<FILE>_H_

1.3 #include路径及顺序

使用完整的项目路径,而不是(或少)使用...定位文件。

如果某个.cpp文件主要是为了实现.h文件中定义的功能,则优先包含该.h文件。

然后依次按照以下顺序包含。

  1. C语言标准库及系统文件
  2. C++语言标准库文件
  3. 第三方库的头文件
  4. 本项目的头文件

2. 命名空间

一个项目内,尽量所有类、普通函数都用命名空间包裹。

命名空间全部顶格写,内部声明或定义的类、函数也要顶格写。

namespace ic {
namespace util {

class Decoder {
};

} // namespace util
} // namespace ic

3. 静态变量和全局变量

尽量不用全局变量,或者以Singleton单例模式替代,手动控制全局变量的初始化顺序。

// init.cpp
Singleton<Foo>::Instance(); // 初始化

// cleanup.cpp
Singleton<Foo>::DesInstance(); // 析构

// main.cpp
auto foo = Singleton<Foo>::GetInstance(); // 获取全局访问点
foo->DoSomething();

4. 类

4.1 结构体 or 类

只有数据成员时使用struct,否则使用class

4.2 声明顺序

相似的声明放在一起,从上到下依次为 public, protected, private

4.3 const

在任何可能的情况下都要使用const

在声明的变量或参数前加上关键字const用于指明变量值不可被篡改

为类中的函数加上const限定符表明该函数不会修改类成员变量的状态。

5. 函数

  • 输入参数:传或者const引用。如果输入值可能为空,也可以考虑const指针
  • 输出参数:指针

6. 命名约定

6.1 文件命名

文件夹、文件名称全部小写,可以使用下划线(_)。C++源文件使用.cpp结尾。文件名称尽量不要与系统默认包含路径的文件重名。

  • geometry_point.h
  • geometry_point.cpp

6.2 类型命名

类型名称每个首字母都大写,不包含下划线,即大驼峰命名方式。

  • class Manager { };
  • class StudentInfo { };

6.3 变量命名

一律小写,单词间使用下划线连接。类(class)成员变量以下划线结尾,结构体(struct)不需要。

// 普通变量
int access_count;
size_t file_size;
size_t filesize;

// 结构体成员变量
struct Foo {
    int access_count;
    size_t file_size;
};

// 类成员变量
class Foo {
public:
private:
    int access_count_ = 0;
    size_t file_size_ = 0;
};

6.4 常量

k开头。

const int kTotalCount = 32;

6.5 (全局)静态变量

s_开头。

static std::string s_buffer;

6.6 全局变量

g_开头。

// main.cpp
#include <iostream>

int g_count = 0;

int main() {
    // ...
    return 0;
}

6.7 函数命名

一般情况

每个首字母大写(大驼峰命名方式),对于首字母缩写的单词, 更倾向于将它们视作一个单词进行首字母大写。

void Start();
void Stop();
int GenerateCode();
std::string GetFileName();

类的取值和设值成员函数

get_set_开头,后面接成员变量名称。

class Foo {
public:
    bool Init();
    void DoSomething();
    std::string GetDns() const;  // not good: GetDNS

    int get_count() const { return count_; }
    void set_count(int c) { count_ = c; }
private:
    int count_ = 0;
};

全局辅助函数

必须在作用域中包裹,函数名称全小写,用下划线连接。

// helper.h
namespace util {
namespace io {

bool write_binary(const std::string& filename, const std::string& content);

bool read_binary(const std::string& filename, std::string* content);

} // namespace io
} // namespace util

6.8 宏

字母全部大写,用下划线分割单词。

#define CHECK() ...
#define CHECK_NUMBER(num) ...

7. 注释

就个人而言,尽量采用 /* */的风格注释,尤其是注释中出现汉字的时候。

8. 代码风格

8.1 行长度

尽量不超过120,最长一定不超过140

8.2 文件编码

统一 UTF-8编码。Linux下默认都是UTF-8编码,Windows下使用Visual Studio编程时文件要手动保存为UTF-8编码(或者安装插件自动编码为UTF-8),同时在项目属性->C/CPP->命令行中添加/utf-8选项。

8.3 缩进

一律使用4个空格,而非制表符。

8.4 函数

大括号与函数签名在同一行。如果参数过长而分为多行,大括号需要另起一行。

void Start() {
    // ...
}

void LongParameterList(int param1, int param2, int param3,
                       int param4, int param5)
{
    // ...
}

void VeryVeryVeryVeryVeryVeryVeryVeryLongFunctionName(
    int param1,
    int param2,
    int param3)
{
    // ...
}

8.5 if / else

ifelse ifelse都另起一行。即使只有一句语句,也要用大括号。

if (x > 100) {
}
else if (x > 10) {
    // ...
}
else {
    // ...
}

8.6 指针/引用定义

*紧跟类型名称,与指针变量名称空一格。定义时必须指向某个地址,或者赋值为空指针nullptr

int value = 99;

int* ptr1 = &value;   // ok
int* ptr2 = nullptr;  // ok
int* ptr3;            // bad!

int& val = value;     // ok

8.7 命名空间

不能增加缩进层次!

namespace foo {

std::string get_value() {  /* 顶格写,不能缩进 */
    // ...
}

} // namespace foo

END

最后更新 2022-08-07
评论 ( 0 )
OωO
隐私评论