一、Header
1.1 Include Guard
一般来说,一个 C++ 程序分为两部分,一部分以 .h 结尾叫做头文件,另一部分以 .cpp 结尾叫做源文件。头文件用来申明诸如函数、类、全局变量,源文件用来定义和实现诸如函数、类的成员。
在编译期间,编译器会将源文件(实际上是头文件)include 进来的源文件串联起来,进行语法分析、生成中间文件,最后生成相应机型的可执行汇编文件。为了避免重复包含同一个源文件,引入 #include guard
。
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
在预处理阶段,预处理器会检查前两行,如果 FILE_H 未被定义,那么 FILE_H 被定义然后执行 define 和 endif 之间的声明;如果 FILE_H 已经被定义了,那么就会跳过。FILE_H 的命名规范:<PROJECT>_<FILE>_H_
,比如项目 foo 有 foo/src/bar/baz.h 头文件,那么就应该有下面的 #include guard
。
#ifndef FOO_BAZ_H
#define FOO_BAZ_H
1.2 Names and Order of Includes
include 一个头文件时,头文件路径从项目的 src 文件夹开始,比如要 include google-awesome-project/src/base/logging.h
,则这么写:
#include "base/logging.h"
为了更好的描述源文件中 include 顺序,举个例子:有一个源文件 dir/foo.cc
实现了 dir2/foo2.h
的声明,我们可以认为 foo.cc 和 foo2.h 紧密关联。那么 include 的顺序就是:
- dir2/foo2.h
- C system files.
- C++ system files.
- Other libraries’ .h files.
- Your project’s .h files.
二、 Naming
2.1 File Names
文件名以小写单词组成,单词之间推荐以 _
隔开。下面是推荐的命名方式:
- my_useful_class.cc
- my-useful-class.cc
- myusefulclass.cc
- myusefulclass_test.cc //_unittest and _regtest are deprecated.
2.2 Type Names
类型名如类、typedef、aliases、枚举,采用和 Java 类似的驼峰命名方式。如:
// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...
// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;
// using aliases
using PropertiesMap = hash_map<UrlTableProperties *, string>;
// enums
enum UrlTableErrors { ...
2.3 Variable Names
2.3.1 Common Variable names
string table_name; // OK - uses underscore.
string tablename; // OK - all lowercase.
string tableName; // Bad - mixed case.
2.3.2 Class Data Members
类成员变量以下划线结尾。
class TableInfo {
...
private:
string table_name_; // OK - underscore at end.
string tablename_; // OK.
static Pool<TableInfo>* pool_; // OK.
};
2.3.3 Struct Data Members
结构体的成员变量和普通变量命名一样。
2.3.4 Constant Names
常量是指在程序运行过程中,值保持不变的变量。以 k 开头,驼峰式命名。
const int kDaysInAWeek = 7;
2.4 Function Names
函数名以驼峰式命名,大写字母开头。
AddTableEntry()
DeleteUrl()
OpenFileOrDie()