GoogleCpp风格指南 8)格式 _part2

8.9 布尔表达式 Boolean Expressions

Tip 如果一个布尔表达式超过标准行宽standard line length; 断行方式要统一一下;

下例中, 逻辑与(&&)操作符总位于行尾:

1
2
3
4
5
if   (this_one_thing > this_other_thing &&
     a_third_thing == a_fourth_thing &&
     yet_another & last_one) {
   ...
}

注意, 上例的逻辑与AND (&&)操作符均位于行尾; Google风格是这样的; 如果是在每行前加上操作符也是允许的; 可以考虑额外插入圆括号, 合理使用的话对增强可读性是很有帮助的;

[Add] 应该总是使用标点punctuation操作符, 如 &&和~ [按位取反], 而不是字符操作符, 如 and和cmpl; <<<


8.10 函数返回值 Return Values

Tip return表达式express中不要用圆括号包围;

函数返回时不要使用圆括号, 除了在 int x = expr 中会使用; [返回表达式]

1
return   x;   // not return(x);

只有在类似这种情况下对retrun表达式使用圆括号: 当你在 int x = expr; 中会使用圆括号的话;

1
2
3
4
return   result;                   // No parentheses in the simple case.
// Parentheses OK to make a complex expression more readable.
return   (some_long_condition &&
         another_condition);

WARNING:

1
2
return   (value);                 // You wouldn't write var = (value);
return (result);                 // return is not a function!


8.11 变量及数组初始化 Variable and Array Initialization

Tip 用 = 或 () 都可以; [Add] or {}. <<<;

从中做出选择: 下面的方式都是正确的:

1
2
3
4
5
6
int   x = 3;
int   x(3);
string name( "Some Name" );
string name =  "Some Name" ;
//[Add]
string name{ "Some Name" };

[Add]

对一个std::initializer_list ctor的类型使用braced initialization list {...}时要小心; 非空的nonempty braced-init-list建议尽量使用std::initializer_list ctor; 注意空的empty braces {}是特殊的, 可能的情况下会调用一个默认ctor; 要强制使用non-std::initializer_list ctor, 使用圆括号代替花括号;

1
2
vector< int > v(100, 1);   // A vector of 100 1s. 100个1
vector< int > v{100, 1};   // A vector of 100, 1.

同时, brace形式还可以防止整型收缩问题narrowing of integral types; 可以防止一些编程错误

1
2
int   pi(3.14);   // OK -- pi == 3.
int   pi{3.14};   // Compile error: narrowing conversion.

<<<


8.12 预处理指令 Preprocessor Directives

Tip 预处理指令不要缩进, 从行首开始: (hash mark)

即使预处理指令位于缩进代码块中, 指令也应从行首开始;

1
2
3
4
5
6
7
8
9
10
// Good - directives at beginning of line
   if   (lopsided_score) {
#if DISASTER_PENDING      // Correct -- Starts at beginning of line
     DropEverything();
# if NOTIFY               // OK but not required -- Spaces after #
     NotifyClient();
# endif
#endif
     BackToNormal();
   }

WARNING

1
2
3
4
5
6
7
// Bad - indented directives
   if   (lopsided_score) {
     #if DISASTER_PENDING  // Wrong!  The "#if" should be at beginning of line
     DropEverything();
     #endif                // Wrong!  Do not indent "#endif"
     BackToNormal();
   }


8.13 类格式 Class Format

Tip 访问控制块的声明依次序是 public, protected, private, 每次缩进一个空格; [默认是没有缩进的]

类声明(对类注释不了解的话, 参考--类注释Class Comments)的基本格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class   MyClass :  public   OtherClass {
  public :       // Note the 1 space indent!
   MyClass();   // Regular 2 space indent.
   explicit   MyClass( int   var);
   ~MyClass() {}
 
   void   SomeFunction();
   void   SomeFunctionThatDoesNothing() {
   }
 
   void   set_some_var( int   var) { some_var_ = var; }
   int   some_var()  const   {  return   some_var_; }
 
  private :
   bool   SomeInternalFunction();
 
   int   some_var_;
   int   some_other_var_;
   DISALLOW_COPY_AND_ASSIGN(MyClass);
};

注意事项:

- 所有基类名应该在80列限制下尽量与子类名放在同一行; (80字符行宽)

- 关键词 public, protected, private要缩进1个空格;

- 除第一个关键词(一般是public)外, 其他关键词要在前面preceded空一行; 如果类比较小的话也可以不空;

- 这些关键词后不要保留空行;

- public放在最前面, 然后是protected, 最后是private;

- 关于声明顺序的规程参考--声明顺序Declaration Order;


8.14 初始化列表 Constructor Initializer Lists

Tip 构造函数初始化列表Constructor initializer lists放在同一行或按四格缩进并排几行;

下面两种初始化列表方式都可以接受;

1
2
// When it all fits on one line:
MyClass::MyClass( int   var) : some_var_(var), some_other_var_(var + 1) {}


1
2
3
4
5
6
7
8
9
// When it requires multiple lines, indent 4 spaces, putting the colon on
// the first initializer line:
MyClass::MyClass( int   var)
     : some_var_(var),              // 4 space indent
       some_other_var_(var + 1) {   // lined up
   ...
   DoSomething();
   ...
}

[有些风格喜欢在初始化列表中, 将逗号写在前面, 那样编辑起来方便点]


8.15 名字空间格式化 Namespace Formatting

Tip 名字空间内容不缩进;

名字空间不要增加额外的缩进层次; 例如:

1
2
3
4
5
6
7
namespace   {
 
void   foo() {   // Correct.  No extra indentation within namespace.
   ...
}
 
  // namespace

不要缩进名字空间;

WARNING:

1
2
3
4
5
6
7
8
namespace   {
 
   // Wrong.  Indented when it should not be.
   void   foo() {
     ...
   }
 
  // namespace

[Add]

在声明嵌套的名字空间时, 把每个名字空间都放在自己独立的行中;

1
2
namespace   foo {
namespace   bar {

<<<


8.16 水平留白 Horizontal Whitespace

Tip 水平留白的使用因地制宜, 永远不要在行尾添加无意义的留白;

常规: General

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void   f( bool   b) {   // Open braces should always have a space before them.
   ...
int   i = 0;   // Semicolons usually have no space before them.
int   x[] = { 0 };   // Spaces inside braces for array initialization are
int   x[] = {0};     // optional.  If you use them, put them on both sides!
 
// Spaces around the colon in inheritance and initializer lists.
class   Foo :  public   Bar {
  public :
   // For inline function implementations, put spaces between the braces
   // and the implementation itself.
   Foo( int   b) : Bar(), baz_(b) {}   // No spaces inside empty braces.
   void   Reset() { baz_ = 0; }   // Spaces separating braces from implementation.
   ...

添加冗余的留白会给其他人在编辑merge时造成额外负担; 因此行尾不要留空格; 如果确定一行代码已经修改完毕, 将多余的空格去掉; 或者在专门清理空格时去掉(确信没有其他人在处理); (译注: 现在大部分代码编辑器稍加设置后, 都支持自动删除行首/尾空格; 如果不支持, 考虑换一款编辑器或IDE);

循环和条件语句: Loops and Conditionals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if   (b) {           // Space after the keyword in conditions and loops.
}  else   {           // Spaces around else.
}
while   (test) {}    // There is usually no space inside parentheses.
switch   (i) {
for   ( int   i = 0; i < 5; ++i) {
switch   ( i ) {     // Loops and conditions may have spaces inside
if   ( test ) {      // parentheses, but this is rare.  Be consistent.
for   (  int   i = 0; i < 5; ++i ) {
for   ( ; i < 5 ; ++i) {   // For loops always have a space after the
   ...                    // semicolon, and may have a space before the
                         // semicolon.
switch   (i) {
   case   1:          // No space before colon in a switch case.
     ...
   case   2:  break   // Use a space after a colon if there's code after it.

[Add]

1
2
3
4
// Range-based for loops always have a space before and after the colon.
for   ( auto   x : counts) {
   ...
}

<<<

操作符 Operators

1
2
3
4
5
6
7
8
9
x = 0;               // Assignment operators always have spaces around
                     // them.
x = -5;              // No spaces separating unary operators and their
++x;                 // arguments.
if   (x && !y)
   ...
v = w * x + y / z;   // Binary operators usually have spaces around them,
v = w*x + y/z;       // but it's okay to remove spaces around factors.
v = w * (x + z);     // Parentheses should have no spaces inside them(internal padding)

[Add]

1
2
3
4
// No spaces separating unary operators and their arguments.
x = -5;
++x;
if   (x && !y)

<<<

模板和转换: Templates and Casts

1
2
3
4
5
6
7
8
9
10
11
12
// No spaces inside the angle brackets (< and >), before
// <, or between >( in a cast
vector<string> x;
y =  static_cast < char *>(x);
 
// Spaces between type and pointer are OK, but be consistent.
vector< char   *> x;
set<list<string>> x;         // Permitted in C++11 code.
set<list<string> > x;        // C++03 required a space in > >.
 
// You may optionally use symmetric spacing in < <.
set< list<string> > x;


8.17 垂直留白 Vertical Whitespace

Tip 垂直留白越少越好

这不仅仅是规则而是原则问题了: 不在万不得已, 不要使用空行, 尤其是: 两个函数定义之间的空行不要超过2行; 函数体首尾不要超过2行; 函数体首位不要留空行, 函数体中也不要随意添加空行;

基本原则是: 同一屏可以显示的代码越多, 越容易理解程序的控制流; 当然, 过于密集dense的代码块和过于疏松的代码块同样难看; 取决于你的判断; 但通常是垂直留白越少越好;

[Remove]

WARNING 函数首尾不要有空行;

1
2
3
4
5
void   Function() {
 
   // Unnecessary blank lines before and after
 
}

WARNING 代码块首尾不要有空行;

1
2
3
4
5
6
7
8
while   (condition) {
   // Unnecessary blank line after
 
}
if   (condition) {
 
   // Unnecessary blank line before
}

if-else块之间空一行是可以接受的;

1
2
3
4
5
6
7
if   (condition) {
   // Some lines of code too small to move to another function,
   // followed by a blank line.
 
}  else   {
   // Another block of code
}

<<<

[Add]

一些关于空行的经验准则rules of thumb:

- 在函数的头尾处的空行可读性不佳;

- 在一系列 if-else块中的空行有助于可读性;

<<<


译者笔记

0) 对于代码格式, 因系统各异有优缺点, 但同一个项目中遵循同一标准还是有必要的;

1) 行宽原则上不超过80列, 把22寸的显示器也占完了; [分辨率到底是有多低...]

2) 尽量不使用非ASCII字符; 如果使用的话, 参考UTF-8格式(尤其是 UNIX/Linux下, Windows下可以考虑宽字符); 尽量不将字符串常量耦合到代码中, 比如独立出资源文件, 这不仅仅是风格问题;

3) UNIX/Linux下无条件使用空格; MSVC的话使用Tab也无可厚非; [用Tab会把code review diff弄成渣]

4) 函数参数, 逻辑条件, 初始化列表: 要么所有参数和函数名放在同一行, 要么所有参数并排分行; 

5) 除函数定义的左大括号可以置于行首外, 包括函数/类/结构体/枚举声明, 各种语句的左大括号置于行尾, 所有右大括号独立成行;

6) ./->操作符前后不留空格, */&不要前后都留, 一个即可, 靠左靠右依照个人喜好; [统一一下]

7) 预处理指令/命名空间不使用额外缩进, 类/结构体/枚举/函数/语句使用缩进;

8) 初始化用 = 还是 () 依照个人喜好, 统一即可;

9) return 不要加 ();

10) 水平/垂直留白不要滥用, 怎么易读怎么来;

11) 关于UNIX/Linux风格为什么要把左大括号置于行尾(.cc文件的函数实现处, 左大括号位于行首); 我的理解是代码看上去比较简约;  行首除了函数体被一对大括号封在一起外, 只有右大括号的代码看上去比较舒服; Windows风格将做大括号置于行首的优点是匹配情况一目了然;

---YCR---


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值