Google C++ 编程规范 ——学习笔记(二)

5.10. 前置自增和自减

对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.

定义:

对于变量在自增 (++i 或 i++) 或自减 (--i 或 i--) 后表达式的值又没有没用到的情况下, 需要确定到底是使用前置还是后置的自增 (自减).

优点:

不考虑返回值的话, 前置自增 (++i) 通常要比后置自增 (i++) 效率更高. 因为后置自增 (或自减) 需要对表达式的值 i 进行一次拷贝. 如果 i 是迭代器或其他非数值类型, 拷贝的代价是比较大的. 既然两种自增方式实现的功能一样, 为什么不总是使用前置自增呢?

缺点:

在 C 开发中, 当表达式的值未被使用时, 传统的做法是使用后置自增, 特别是在 for 循环中. 有些人觉得后置自增更加易懂, 因为这很像自然语言, 主语 (i) 在谓语动词 (++) 前.

结论:

对简单数值 (非对象), 两种都无所谓. 对迭代器和模板类型, 使用前置自增 (自减).

5.11. const 的使用

我们强烈建议你在任何可能的情况下都要使用 const.

定义:

在声明的变量或参数前加上关键字 const 用于指明变量值不可被篡改 (如 const int foo ). 为类中的函数加上 const 限定符表明该函数不会修改类成员变量的状态 (如 class Foo { int Bar(char c) const; };).

优点:

大家更容易理解如何使用变量. 编译器可以更好地进行类型检测, 相应地, 也能生成更好的代码. 人们对编写正确的代码更加自信, 因为他们知道所调用的函数被限定了能或不能修改变量值. 即使是在无锁的多线程编程中, 人们也知道什么样的函数是安全的.

缺点:

const是入侵性的: 如果你向一个函数传入 const 变量, 函数原型声明中也必须对应 const 参数 (否则变量需要 const_cast 类型转换), 在调用库函数时显得尤其麻烦.

结论:

const 变量, 数据成员, 函数和参数为编译时类型检测增加了一层保障; 便于尽早发现错误. 因此, 我们强烈建议在任何可能的情况下使用 const:

 如果函数不会修改传入的引用或指针类型参数, 该参数应声明为 const.

 尽可能将函数声明为 const. 访问函数应该总是 const. 其他不会修改任何数据成员, 未调用非 const 函数, 不会返回数据成员非 const 指针或引用的函数也应该声明成 const.

 如果数据成员在对象构造之后不再发生变化, 可将其定义为 const.

然而, 也不要发了疯似的使用 const. 像 const int * const * const x; 就有些过了, 虽然它非常精确的描述了常量 x. 关注真正有帮助意义的信息: 前面的例子写成 const int** x 就够了.

关键字 mutable 可以使用, 但是在多线程中是不安全的, 使用时首先要考虑线程安全.

const 的位置:

有人喜欢 int const *foo 形式, 不喜欢 const int* foo, 他们认为前者更一致因此可读性也更好: 遵循了 const 总位于其描述的对象之后的原则. 但是一致性原则不适用于此, “不要过度使用” 的声明可以取消大部分你原本想保持的一致性. 将 const 放在前面才更易读, 因为在自然语言中形容词 (const) 是在名词 (int) 之前.

这是说, 我们提倡但不强制 const 在前. 但要保持代码的一致性! (yospaly 注: 也就是不要在一些地方把 const 写在类型前面, 在其他地方又写在后面, 确定一种写法, 然后保持一致.)

5.12. 整型

C++ 内建整型中, 仅使用 int. 如果程序中需要不同大小的变量, 可以使用 <stdint.h> 中长度精确的整型, 如 int16_t.

5.15. 0 和 NULL

整数用 0, 实数用 0.0, 指针用 NULL, 字符 (串) 用 '\0'.

整数用 0, 实数用 0.0, 这一点是毫无争议的.

对于指针 (地址值), 到底是用 0 还是 NULL, Bjarne Stroustrup 建议使用最原始的 0. 我们建议使用看上去像是指针的 NULL, 事实上一些 C++ 编译器 (如 gcc 4.1.0) 对 NULL 进行了特殊的定义, 可以给出有用的警告信息, 尤其是 sizeof(NULL) 和 sizeof(0) 不相等的情况.

字符 (串) 用 '\0', 不仅类型正确而且可读性好.

 

命名约定

6.1. 通用命名规则

函数命名, 变量命名, 文件命名应具备描述性; 不要过度缩写. 类型和变量应该是名词, 函数名可以用 “命令性” 动词

如何命名:

 尽可能给出描述性的名称不要节约行空间让别人很快理解你的代码更重要好的命名风格:

 

        int num_errors;                  // Good.

        int num_completed_connections;   // Good.

    糟糕的命名使用含糊的缩写或随意的字符:

        int n;                           // Bad - meaningless.

        int nerr;                        // Bad - ambiguous abbreviation.

        int n_comp_conns;                // Bad - ambiguous abbreviation.

    类型和变量名一般为名词如 FileOpener, num_errors.

函数名通常是指令性的 (确切的说它们应该是命令), 如 OpenFile(), set_num_errors(). 取值函数是个特例 (在 函数命名 处详细阐述), 函数名和它要取值的变量同名.

6.2. 文件命名

文件名要全部小写, 可以包含下划线 (_) 或连字符 (-). 按项目约定来.

6.3. 类型命名

类型名称的每个单词首字母均大写, 不包含下划线: MyExcitingClass, MyExcitingEnum

 

6.4. 变量命名

变量名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾

6.5. 常量命名

在名称前加 k: kDaysInAWeek.

所有编译时常量, 无论是局部的, 全局的还是类中的, 和其他变量稍微区别一下. k 后接大写字母开头的单词::

const int kDaysInAWeek = 7;

注释

 关于注释风格,很多 C++ 的 coders 更喜欢行注释, C coders 或许对块注释依然情有独钟, 或者在文件头大段大段的注释时使用块注释;

 文件注释可以炫耀你的成就, 也是为了捅了篓子别人可以找你;

 注释要言简意赅, 不要拖沓冗余, 复杂的东西简单化和简单的东西复杂化都是要被鄙视的;

 对于 Chinese coders 来说, 用英文注释还是用中文注释, it is a problem, 但不管怎样, 注释是为了让别人看懂, 难道是为了炫耀编程语言之外的你的母语或外语水平吗;

 注释不要太乱, 适当的缩进才会让人乐意看. 但也没有必要规定注释从第几列开始 (我自己写代码的时候总喜欢这样), UNIX/LINUX 下还可以约定是使用 tab 还是 space, 个人倾向于 space;

 TODO 很不错, 有时候, 注释确实是为了标记一些未完成的或完成的不尽如人意的地方, 这样一搜索, 就知道还有哪些活要干, 日志都省了.

格式

8.4. 函数声明与定义

返回类型和函数名在同一行, 参数也尽量放在同一行.

函数看上去像这样:

ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {

    DoSomething();

    ...

}

 

如果同一行文本太多, 放不下所有参数:

ReturnType ClassName::ReallyLongFunctionName(Type par_name1,

                                             Type par_name2,

                                             Type par_name3) {

    DoSomething();

    ...

}

 

甚至连第一个参数都放不下:

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(

        Type par_name1,  // 4 space indent

        Type par_name2,

        Type par_name3) {

    DoSomething();  // 2 space indent

    ...

}

 

注意以下几点:

· 返回值总是和函数名在同一行;

· 左圆括号总是和函数名在同一行;

· 函数名和左圆括号间没有空格;

· 圆括号与参数间没有空格;

· 左大括号总在最后一个参数同一行的末尾处;

· 右大括号总是单独位于函数最后一行;

· 右圆括号和左大括号间总是有一个空格;

· 函数声明和实现处的所有形参名称必须保持一致;

· 所有形参应尽可能对齐;

· 缺省缩进为 2 个空格;

· 换行后的参数保持 4 个空格的缩进;


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值