C++格式规范,《google开源项目风格指南》笔记

//这是《google开源项目风格指南》C++版本的笔记,如果对其中内容感兴趣可以去找原书看。感谢作者和译者,救我小命。

C++特性

所有按引用传递的参数必须加上const

更推荐用printf+read/write instead of I/O流

对于迭代器和模板类型,使用前置自增自减

前提:c++中人们假定short是16位,Int 32位,long 32位,long long 64位。如果需要不同大小的整型变量,可以借助<stdint.h>中长度精确的整型,其中包括int16_t,uint_32_t,int64_t…其余问题不是老奴该关心的。

继承可以通过复用基类代码减少代码量

一般来说类的属性成员都应设置为private,public只留给外部调用的函数接口

头文件 扩展名为.h,包含C的函数声明和宏定义,有程序员编写的头文件和C标准库自带头文件,要使用头文件,需用预处理指令#include进行引用,饮用后可以使用头文件中声明的函数。

#include 预处理指令分两种,# include<> 引用系统头文件,#include "" 引用用户程序目录中的头文件,找不到去系统头文件里找。

内联函数 关键词 inline 放在函数定义前,可以将函数定义为内联函数,从而内联地展开,提升运行速度,但内联函数的语句一般不超过10行,超过就没必要内联了。如果内联包含循环/switch的函数,往往得不偿失。

//对于变量的声明/定义:声明是为了告诉编译器变量的类型和名称,而不申请存储空间,定义申请存储空间,可以赋初值,在C++中,二者区分不大,往往同时发生

对于函数的声明/定义:函数只要有实现(存在函数体 { …… } )即为定义,否则为声明。可以这样理解:函数声明是说明函数是什么,函数定义是说明函数做什么。

声明和定义的区别:

1.声明/定义次数_变量/函数可以声明多次,变量/函数的定义只能一次。

2.分配内存_声明不会分配内存,定义会分配内存。

3.做了什么_声明是告诉编译器变量或函数的类型和名称等,定义是告诉编译器变量的值,函数具体干什么。

C++允许函数在任何位置声明变量,将变量尽可能置于最小作用域内,而且相较于声明再赋值,最好一开始就初始化。

C++书写格式

每行代码字符数不超过80,尽量不要加空行

预处理指令永远从行首开始,不缩进,即使它处于缩进代码块中。

关于空格的不完全梳理

不使用制表位,需要有空格时输入空格,且每次缩进2个空格。

左大括号前总有空格,在列表初始化时大括号内的空格是optional,对于单行函数的实现,需要加空格。

分号前不加空格,循环内的分号后总有空格,且前面可以加一个空格。

赋值运算符前后总是有空格,其他二元操作符也是,不过表达式的子式可以不加空格。在参数和一元操作符之间不加空格。

switch case 的冒号前没有空格,如果后面有代码,冒号后加空格。

< >:“<”前无空格,内部也没有空格,“>”后的话,后跟(则无空格,跟变量有空格。

vector<string> x;
y = static_cast<char*>(x);
vector<char *> x;  //可以在类型与指针操作符之间留空格哈

参数

在进行函数声明与定义时,返回类型和函数名放在同一行,如果放不下就对形参进行分行。在进行函数调用的时候同理。分行方式:

1.在括号内进行分行,参数应尽量对齐;

ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,
                                             Type par_name3) {
  DoSomething();
  ...
}

2.将参数另起一行,分行书写,且开头缩进四格; 

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
    Type par_name1,  // 4 space indent
    Type par_name2,
    Type par_name3) {
  DoSomething();  // 2 space indent
  ...
}

3.如果一系列参数本身就有一定的结构,可以酌情按其结构来决定参数格式;

my_widget.Transform(x1, x2, x3,
                    y1, y2, y3,
                    z1, z2, z3);

如果一些参数本身就是略复杂的表达式,且降低了可读性,可直接创建临时变量描述该表达式,并传递给函数。

int my_heuristic = scores[x] * y + bases[x];
bool retval = DoSomething(my_heuristic, x, y, z);
  • 使用好的参数名.
  • 只有在参数未被使用或者其用途非常明显时, 才能省略参数名.
  • 如果返回类型和函数名在一行放不下, 分行.
  • 如果返回类型与函数声明或定义分行了, 不要缩进.
  • 左圆括号总是和函数名在同一行.
  • 函数名和左圆括号间永远没有空格.
  • 圆括号与参数间没有空格.
  • 左大括号总在最后一个参数同一行的末尾处, 不另起新行.
  • 右大括号总是单独位于函数最后一行, 或者与左大括号同一行.
  • 右圆括号和左大括号间总是有一个空格.
  • 所有形参应尽可能对齐.(像第一段代码那样)
  • 缺省缩进为 2 个空格.
  • 换行后的参数保持 4 个空格的缩进.

变量及数组初始化:有=/()/{}三种方式

int x = 3;
int x(3);
int x{3};

列表初始化:这个作者可文明了,他说“您平时怎么格式化函数调用,就怎么格式化列表初始化”。列表初始化中大括号内的空格可写可不写,如果加了,那么两边都要加上。{0}/{ 0 }都可

条件语句:在圆括号内不使用空格,圆括号外前后各一个空格,else与if的右括号同一行,当语句简单且没有使用else子句时,可以将条件语句直接写在同一行,否则达咩。通常单行语句不需要使用大括号,但想用也没人拦你。

开关选择语句:case可用大括号也可不用,如果有不满足 case 条件的枚举值, switch 应该总是包含一个 default 匹配 (如果有输入值没有 case 去处理, 编译器将给出 warning). 如果 default 应该永远执行不到, 简单的加条 assert:

switch (var) {
  case 0: {  // 2 空格缩进
    ...      // 4 空格缩进
    break;
  }
  case 1: {
    ...
    break;
  }
  default: {
    assert(false);
  }
}

循环语句:单语句循环,括号可用可不用,空循环体应使用{}或continue

for (int i=0; i<kSomeNumber; ++i) {}  //空循环体
while (contition) continue;  continue表示没有逻辑

指针和引用表达式

在访问成员时,句点或箭头前后不要有空格,指针/地址操作符(*,&)之后不能有空格

foo = *p;
p = &x;
x = Boo.son;
x = Boo->son;

在声明指针变量或参数时,型号与类型或变量名紧挨都可以,是一样滴。

返回值:返回值又不是函数参数,不要加圆括号,除非为了将复杂表达式圈起来改善可读性

:声明次序是public:,protected:,private:, 这三个关键词要缩进一个空格,其他语句正常缩2个空格。继承与初始化列表中的冒号前后永远有空格

构造函数初始值列表

还是和参数一样的原则,能一行排开就一行排开,排不开就换行/多行排,排得整齐点。

//能放同一行的话:
MyClass::MyClass(int var):some_var_(var) {
  FaireFaire();
}
//不能放同一行,先试试换行不跟声明定义放一块行不行:(tip:从冒号开始换行,并缩进4空格)
MyClass::MyClass(int var)
    :some_var_(var),some_other_var_(var + 1) {
  FaireFaire();
}
//换行还不够用就拆开呗(注意对齐)
MyClass::MyClass(int var)
    :some_var_(var),
     some_other_var_(var + 1) {
  FaireFaire();
}

命名约定

一些特定且广为人知的缩写是允许的,例如用i表示迭代变量,用T表示模板参数,尽量不要用一些除了你没几个人能懂什么意思的缩写。

文件命名:全部小写,可以包含_或-,一般_更好。C++文件要以.cc结尾,头文件要以.h结尾,专门插入文本的文件则以.inc结尾。内联函数必须放在.h文件中。

类型命名:要以大写字母开始,每个单词首字母均大写,不包含下划线。包含类、结构体、类型定义(typedef)、枚举,类型模板参数等。

变量/数据成员命名:一律小写,单词间可用下划线连接,类的成员变量以下划线结尾,结构体的数据成员不用。

常量命名:声明为constexpr/const的变量,命名时以”k"开头,大小写混合。所有具有静态存储类型的变量都应以此方式命名。

                  eg. const int kDaysInAWeek = 7;

函数命名:一般使用驼峰变量名(就是前面说的开头大写啦),无下划线,首字母缩写构成的单词一般倾向于视为一个单词进行首字母大写  eg.StartRpc() instead of StartRPC()

枚举命名:kEnumName  ENUM_NAME,最好优先选择常量风格的命名方式。

宏命名

 嗯嗯嗯你说得对

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值