-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcppsyntx.txt
676 lines (565 loc) · 25.2 KB
/
cppsyntx.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
863
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
= C++ 编码规范 =
南京第55所技术开发有限公司
v1.0.0, 2013-11-25: 初始版本.
:Author Initials: 李武祥
:toc:
:icons:
:numbered:
== 前言 ==
本文描述了C++语言代码的规范,其中目录结构参考了 _Google 开源项目风格指南_ ,同时里面的一小部分直接引用其原文,这里感谢Google的贡献.
既然我们有了 _Google 开源项目风格指南_ ,为什么我在这里还有重复造轮子呢?
首先 _Google 开源项目风格指南_ 篇幅比较长,不太适合在培训(自己想提升C\+\+水平可以自己去看看),内容太长大家听的就没劲,同时里面的一些技术我们很少用到.
其次我集合了我们以前项目和现在的项目所用到的C++知识和项目里面存在的代码问题,我浓缩了Google的编码规范,并且添加了一些我们项目里面遇到的比较多的问题,
这个编码规范可能随着我们的项目进行会有所添加.
*版权所有 (C) 南京第55所技术开发有限公司 2012-2013 保留一切权利.*
== 头文件 ==
=== #define保护 ===
*所有的头文件都应该使用#define包含起来防止重复包含,命名<PROJECT>_<PATH>_<FILE>_H*
头文件的命名应该依据所在项目源代码树的全路径,但是要去除src目录,假设我们在src目录组织下有个util目录下面有个util.h
[source,c,numbered]
------------------------------
#ifndef UTIL_MISC_H
#define UTIL_MISC_H
...
#endif /* UTIL_MISC_H */
------------------------------
不要使用非标准的扩展#pragma once.
=== 头文件依赖 ===
*能使用前置声明的地方就不要使用#include*
为了减少依赖并且,加快编译速度,在头文件里我们都是尽量使用前置声明,而不是用#include,
然而这样做的是有前提条件的,那就是头文件里的定义对象(一般来说是类的成员变量),必须是指针
或者是引用.
[list]
--------------------------------------
#ifndef MYCLASS_H
#define MYCLASS_H
//#include "widget.h"
//#include "log.h"
class Widget;
Class Loger;
class Myclass {
.....
private:
int count;
Widget *_widget; // pointer
Loger& _log; //refrence
}
#endif /* _MYCLASS_H_ */
--------------------------------------
=== 头文件的顺序 ===
头文件的顺序按照如下包含
* 标准库头文件
* 系统相关头文件
* 第三库头文件
* 本程序的头文件
且除了工程的程序的头文件外一律使用<>,本工程下的头文件使用""
[list]
---------------------------------
#include <iostream> // 标准库
#include <windows.h> //系统API库
#include <boost/boost.h> //第三方库头文件
#include "misc.h" //本工程下的头文件
---------------------------------
=== 内联函数 ===
只有当函数只有 10 行甚至更少时才将其定义为内联函数.
定义:
当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.
优点:
当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
缺点:
滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快.
结论:
一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!
另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行).
有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联
== 作用域 ==
=== 局部变量 ===
将函数变量尽可能置于最小作用域内, 并在变量声明时进行初始化.
C++包括C99语法都可以在函数的任何位置声明变量,所以变量声明"越迟越好",即在使用的地方再去声明定义
[list]
------------------------------------
std::string str;
str = getText(); // bad 初始化和声明分离
std::string text = getText(); //good 初始化和声明一起
int fun(const char* str)
{
std::string s; //bad 如果str为空这里的构造函数开销就白做了
if(!str)
return -1;
s = str;
MyClass class; //good 在需要的地方再去定义
class.setText(str);
class.doSth();
return 0;
}
------------------------------------
现在的VC和GCC编译器都实现了在循环语句的作用域里,即使用如下形式,同时这里有个不成文的的规定,循环在没有特殊的情况下使用i和j.
[list]
-------------------------------------------------------
for(int i=0; i<count; ++i) { //good
// do sth...
} //i出了这个作用域就销毁了,所以后面再使用是完全没有问题的
....
for(int i=0; i<size; ++i) {
for(int j=0; j<count; j++) {
//do other things...
}
}
--------------------------------------------------------
如果变量是一个对象, 每次进入作用域都要调用其构造函数, 每次退出作用域都要调用其析构函数(内置类型的变量没有构造和析构的开销)
[list]
---------------------------------------------------------
// 低效的实现
for(int i=0; i<1000000; ++i) {
Foo f; // 构造函数和析构函数分别调用 1000000 次!
bool result = f.DoSomething(i); //这里的result除外
if(result ==0)
break;
}
----------------------------------------------------------
放在循环的外部则高高效很多
[list]
----------------------------------------------------------
Foo f; // 构造函数和析构函数只调用 1 次
for (int i=0; i<1000000; ++i) {
bool result = f.DoSomething(i); //但是对于内置类型来说,这样写是可以的
if(result ==0) //这样的代码更美观,同时几乎没有性能损失
break;
}
-----------------------------------------------------------
这里的规则同样适用于while语句和if语句的作用域,这里就不再赘述.
=== 静态或全局变量 ===
禁止使用 class 类型的静态或全局变量: 它们会导致很难发现的 bug 和不确定的构造和析构函数调用顺序.
=== 嵌套类 ===
当公有嵌套类作为接口的一部分时, 虽然可以直接将他们保持在全局作用域中, 但将嵌套类的声明置于名字空间内是更好的选择.
=== 命名空间 ===
鼓励在 .cpp 文件内使用匿名名字空间. 使用具名的名字空间时, 其名称可基于项目名或相对路径. 不要使用 using 关键字.
== 类 ==
=== 构造函数 ===
构造函数应对内置的数据类型做初始化,因为这些数据没有自己的构造函数,在类内部他们的值是不确定的,对象类型不需要初始化
而且我们应该使用初始化列表而不是使用赋值的方式,初始化的顺序应该和定义的顺序保持一致
[list]
--------------------------------------------
...
class Rect {
public:
Rect();
~Rect();
private:
int _x;
int _y;
int _width;
int _height;
std::string _name;
};
Rect::Rect() :
_x(0),
_y(0), //初始化和定义的顺序保持一致
_width(0),
_height(0)
{
//_x = 0;
//_y = 0; //虽然没有错,但是不鼓励这样写
//这是赋值不是初始化,有些需要参数的类就不能这样写了
...
}
...
--------------------------------------------
构造函数的一些说明:
* 不要使用默认的构造函数,应该自己去定义一个并且初始化内置成员,可以解决如上讲到的问题.
* 显式构造函数,对单个参数的构造函数使用 C++ 关键字 explicit,这样可以避免不合时宜的变换.
* 拷贝构造函数,对于不需要复制的类要自己定义一个复制构造函数,而不是依赖编译器默认生成的并且将他声明为private.
[list]
-----------------------------------------------
class Log{
public:
Log();
~Log();
private:
Log(const Log& log); // 定义为私有的这样就可以防止复制了
void operator=(const Log& log);
}
-----------------------------------------------
=== 结构体 VS 类 ===
仅当只有数据时使用 struct, 其它一概使用 class.
在 C++ 中 struct 和 class 关键字几乎含义一样. 我们为这两个关键字添加我们自己的语义理解, 以便为定义的数据类型选择合适的关键字.
struct 用来定义包含数据的被动式对象, 也可以包含相关的常量, 但除了存取数据成员之外, 没有别的函数功能. 并且存取功能是通过直接访问位域 (field), 而非函数调用. 除了构造函数, 析构函数, 不能提供其它功能的函数.
如果需要更多的函数功能, class 更适合. 如果拿不准, 就用 class.
=== 多重继承 ===
目前来讲我们几乎用不到多重继承,同时我们不鼓励使用多重继承,只在以下情况我们才允许多重继承:最多只有一个基类是非抽象类; 其它基类都是以 Interface 为后缀的 纯接口类.
=== 存取控制 ===
将所有数据成员声明为 private, 并根据需要提供相应的存取函数. 例如, 某个名为std::string _name的变量, 其取值函数是
name(). 同时还可能需要一个赋值函数 setName()
一般在头文件中把存取函数定义成内联函数.
具体细节见函数命名.
=== 声明顺序 ===
在类中使用特定的声明顺序: public: 在 private: 之前, 成员函数在数据成员 (变量) 前
类的访问控制区段的声明顺序依次为: public:, protected:, private:. 如果某区段没内容, 可以不声明,并且数据和函数使用不同区段.
下面是类的每个区段声明顺序
* typedefs 和枚举
* 常量
* 构造函数
* 析构函数
* 成员函数, 含静态成员函数
* 数据成员, 含静态数据成员
=== 编写简短的函数 ===
倾向编写简短, 凝练的函数.
我们承认长函数有时是合理的, 因此并不硬性限制函数的长度. 如果函数超过 40 行, 可以思索一下能不能在不影响程序结构的前提下对其进行分割.
即使一个长函数现在工作的非常好, 一旦有人对其修改, 有可能出现新的问题. 甚至导致难以发现的 bug. 使函数尽量简短, 便于他人阅读和修改代码.
在处理代码时, 你可能会发现复杂的长函数. 不要害怕修改现有代码: 如果证实这些代码使用 / 调试困难, 或者你需要使用其中的一小段代码, 考虑将其分割为更加简短并易于管理的若干函数.
== C++特性 ==
=== 使用C++的强制类型转换 ===
在C\+\+里面写代码不要使用C语言的强制类型转换,请使用C++的强制类型.
[list]
----------------------------------------------------
int x=(int)y; //bad
int x=static_cast<int>(y); // good
----------------------------------------------------
下面再对C++提供的4种强制类型转换作简要的说明,在使用的时候应严格按照本文档的描述
* 用 static_cast 替代 C 风格的值转换, 或某个类指针需要明确的向上转换为父类指针时.
* 用 const_cast 去掉 const 限定符.
* 用 reinterpret_cast 指针类型和整型或其它指针之间进行不安全的相互转换. 仅在你对所做一切了然于心时使用.
* dynamic_cast 测试代码以外不要使用. 除非是单元测试, 如果你需要在运行时确定类型信息, 说明有 设计缺陷.
=== 前置自增和自减 ===
对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.不考虑返回值的话, 前置自增 (++i) 通常要比后置自增 (i++) 效率更高.
因为后置自增 (或自减) 需要对表达式的值 i 进行一次拷贝对于其他非数值类型, 拷贝的代价是比较大的.对于数值型的变量前自增, 自减效率没有
什么影响.
=== const的引用 ===
我们强烈建议你在任何可能的情况下都要使用 const.
const的好处还是比较多的,我这里就不说明了,可以自己去Google,这里仅对定义const对象时const的位置做规定
[list]
--------------------------------
std::string const str("I am a string"); //bad 这个语法是正确的但是在我们规范不推荐使用
const std::string str("I am a string"); //good 我们应该总是要这样的方式
--------------------------------
=== sizeof ===
尽可能用 sizeof(varname) 代替 sizeof(type).
使用 sizeof(varname) 是因为当代码中变量类型改变时会自动更新
[list]
-----------------------------------------
Struct data;
Struct *data1 = new Struct;
std::memset(&data, 0, sizeof(Struct)); //bad
std::memset(data1, 0, sizeof(Struct)); //bad
std::memset(&data, 0, sizeof(Struct)); //good
std::memset(data1, 0, sizeof(*data1)); //good
-----------------------------------------
=== C++11新特性 ===
对于现有的工程我们不允许使用C++11的新东西,你图个新鲜可能会给整个工程带来麻烦.
== 命名约定 ==
=== 文件命名 ===
文件名要全部小写,可以接受"_"其他字符不要使用,不要使用标准库和第三方库已经有的文件名.
[list]
----------------------------------------------
devicemanage.h //good
devicemanage.cpp //good
deviceManage.h //bad
DeviceManage.cpp //bad
----------------------------------------------
=== 类型命名 ===
*类型名称的每个单词首字母均大写, 不包含下划线*
所有的类,结构体, 枚举和类型定义 (typedef)均使用相同的命名规则
[list]
-----------------------------------------------
// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...
// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;
// enums
enum UrlTableErrors { ...
-----------------------------------------------
=== 变量命名 ===
变量不要使用缩写,使用整个单词,命名规则为首单词第一个字母小写,其他字母大写(公认缩写除外如http, rtsp)
[list]
------------------------------------------------
std::string usr; //bad
std::string psw; //bad
std::string tablename; //bad
int num = 0; //bad
int w; //bad
int tempValueDay; //bad 任何时候不要在变量前面或后面加tmp(temp),也不要在字符串前后加str
Device aDevice; //bad 不要使用这种命名或者oneDevice的命名方式,直接使用单数就可以表示了
std::string username; //good
std::string password; //good
std::string tableName; //good 我们推荐这种做法
int number = 0; //good
int width = 0; //good
Device device; //good
------------------------------------------------
对于类的成员变量统一在前面加"_"
[list]
------------------------------------------------
class MyClass {
.....
private:
int _day;
std::string _name;
.....
};
------------------------------------------------
结构体成员不要加任何前后缀,因为结构体里是存放的纯数据
[list]
------------------------------------------------
struct Rect{
int x;
int y;
int width;
int height;
};
------------------------------------------------
=== 函数命名 ===
函数命名和变量命名相同,采用首单词第一个字母小写其他单词首字母大写的方式,不要使用"-"和"_"字符.
[list]
--------------------------------------------------
QString name()const { return _name;};
void setName(const QString &name) { _name = name;};
int setupWidgets();
---------------------------------------------------
=== 枚举命名 ===
枚举值全部采用大写,同时允许使用"-"字符.
[list]
-------------------------------------------------------
enum VideoRendererType {
VIDEO_RENDER_NULL = 0, ///< 无
VIDEO_RENDER_DEFAULT, ///< 库内默认
VIDEO_RENDER_DIRECT2D, ///< Direct 2D
VIDEO_RENDER_DIRECT3D, ///< Direct 3D
VIDEO_RENDER_DIRECTSHOW_VMR7, ///< VMR7
VIDEO_RENDER_DIRECTSHOW_VMR9, ///< VMR9
VIDEO_RENDER_DIRECTSHOW_EVR, ///< EVR
VIDEO_RENDER_DIRECTDRAW, ///< DirectDraw
VIDEO_RENDER_GDI, ///< GDI
VIDEO_RENDER_OPENGL, ///< OpenGL
VIDEO_RENDER_SDL, ///< SDL
};
-------------------------------------------------------
=== 宏命名 ===
通常情况下不推荐使用宏,除非迫不得已宏采用形式:MY_MACRO_MAX_XXX
[list]
---------------------------------------------------
#define MAX_SUPPORTED_CHANNELS 64
---------------------------------------------------
== 注释 ==
使用 // 或 /* */, 统一就好,在C++中使用//更多一些,但是绝对不要添加那些毫无意义的注释.
对于用英文注释还是用中文注释,实这个问题不好说,尽量使用你擅长的语言,注释是为了让别人看懂而不是为了炫耀.
=== 文件注释 ===
文件注释使用统一的格式,虽然文件注释会让人有成就感,但是要记住出了问题也好找你.
[list]
---------------------------------------------------
/*
* main.cpp
*
* History:
* 2013/01/10 - [lwx] created file
*
* Copyright (C) 2011-2013, Cetc55, Inc. All rights reserved.
*
*/
----------------------------------------------------
=== 类注释 ===
接口类对外要有详细的说明
=== 变量注释 ===
单个变量一般情况下无需注释,我们从变量命名就可以看出你的意思
=== 函数注释 ===
函数的注释只需要放在声明处即可,实现处不需要再放置注释,函数的注释规则如下:
* 函数的输入输出.
* 对类成员函数而言: 函数调用期间对象是否需要保持引用参数, 是否会释放这些参数.
* 如果函数分配了空间, 需要由调用者释放.
* 参数是否可以为 NULL.
* 是否存在函数使用上的性能隐患.
* 如果函数是可重入的, 其同步前提是什么?
=== 实现注释 ===
对于代码中巧妙的, 晦涩的, 有趣的, 重要的地方加以注释.
[list]
------------------------------------------------
// Divide result by two, taking into account that x
// contains the carry from the add.
for (int i = 0; i < result->size(); i++) {
x = (x << 8) + (*result)[i];
(*result)[i] = x >> 1;
x &= 1;
}
------------------------------------------------
=== TODO 注释 ===
对那些临时的, 短期的解决方案, 或已经够好但仍不完美的代码使用 TODO 注释.TODO采用全大写的单行注释
[list]
--------------------
//TODO
---------------------
== 格式 ==
=== 行长度 ===
每一行代码字符数不超过 80.这个是历史遗留的问题,虽然现在很多机器上都装了22英寸的显示器,但是把它占满还是不太好的.
=== 空格还是制表位 ===
*只使用空格, 每次缩进 4 个空格.*
我们使用空格缩进. 不要在代码中使用制符表. 你应该设置编辑器将制符表转为空格.
=== 函数声明与定义 ===
返回类型和函数名在同一行, 参数也尽量放在同一行,函数的2个花括号单独占一行.
[list]
-------------------------------------------------------------------
int MyClass::function(int arg1, const QString &arg2)
{
doSomething();
...
return 0;
}
//函数与函数之间保持一个空行不要多,也不要少
std::string MyClass::name() const //如果有const属性也放在同一行
{
return _name;
}
--------------------------------------------------------------------
=== 条件语句 ===
不在圆括号内使用空格. 关键字 else 另起一行,本规范采用花括号和if等在一行的准则,圆括号和花括号之间留一个空格.
[list]
--------------------------------------------------------------------
if(condition) { //留一个空格,同时"()"里2边不要留空格
.....
}
else { //单独一行留一个空格
.....
}
---------------------------------------------------------------------
只有一个简单条件语句我们允许不加"{}",但是如果一方加了,那么你也要加上,必须保持项目的一致性.
[ist]
---------------------------------------------------------------------
if(result != 0)
return -1;
if(result !=0)
return -1;
else
return 0;
if(result !=0) { //bad,不要一边加了{}一边不加
return -1;
}
else
return 0;
---------------------------------------------------------------------
如果能增强可读性, 简短的条件语句允许写在同一行. 只有当语句简单并且没有使用 else 子句时使用,注意不要滥用,同时坚决抵制有else时
写在一行.
[list]
---------------------------------------------------------------------
if (x == 2) return new Wiegt();
if (x == 3) return new ToolBar();
if(x==2) return new Widget(); //bad 我们不允许这么做
else return new ToolBar();
---------------------------------------------------------------------
=== 循环和开关选择语句 ===
循环和开关选择语句的规范和if一致需要补充的是开关语句,不要在case里面加"{}".
[list]
---------------------------------------------------------------------
switch(mode) {
case 1:
showNomal();
//doSomting.
break;
case 2:
showfullscreen();
break;
default:
break;
}
switch(mode) {
case 1: //bad我们不允许这么做
{
showNomal();
//doSomting.
break;
}
case 2:
{
showfullscreen();
break;
}
default:
{
break;
}
}
------------------------------------------------------------------------
=== 针和引用表达式 ===
指针/地址操作符 (*, &) 之后不能有空格,同时(*,&)与变量靠一起.
[list]
---------------------------------------------------
char *head,*next;
int &number; //good 我们采用这种做法
char* head,next; //bad 这里有时候还会卒伍的认为next也是个指针
int& number;
char * str; //bad 绝对不要出现这种情况
---------------------------------------------------
=== 布尔表达式 ===
对于一般的bool表达式没有问题,但是有时候我们一次会判断几个条件(if/while),是的bool表的是很长,我们断行时把逻辑运算符放在后面.
[list]
---------------------------------------------------
if(condition1 > condition2 &&
condition3 < condition4 &&
condition1 > 100) {
// do something.
}
---------------------------------------------------
=== 函数返回值 ===
return 表达式中不要用圆括号包围.
[list]
--------------------------------------------------
return -1; //good
return (-1); //bad
--------------------------------------------------
=== 变量及数组初始化 ====
内置类型使用=赋值,对象采用()初始化
[list]
--------------------------------------------------
int x=0; //good
std::string str("Good boy!");
int x(0); //bad
std::string str = "Bad guy!";
--------------------------------------------------
=== 预处理指令 ===
预处理指令要顶行写,即使在缩进的代码快里
[list]
-----------------------------------------------------
if(...) {
QString name;
#ifdef Q_OS_WIN //注意时刻保持预处理指令顶行
name = "Platform:Windows";
#else
name = "Platform:Others";
#endif
show(name);
}
-----------------------------------------------------
=== 水平和垂直留白 ===
不要在行前后行尾留无意义的空格,水平留白用在定义变量,变量赋值等等(参见示例代码),不要滥用垂直留白,垂直留白一次只留一个空行.
[list]
-----------------------------------------------------
std::string type;
int index = getCurrentItemIndex(); //注意水平的空格
//变量的定义和语句块之间留一个空行
if(index == -1) {
return 0;
}
if(index > 0 && index <100) {
type = "In";
else
typr = "Out";
// do somthing ...
}
// 注意函数的参数空格留白方式“,”紧贴变量
int MyClass::setClassAttr(int id, int type, const std::string &name);
//for 语句也是一样
for(int i=0; i<100; i++) {
// loop
}
--------------------------------------------------------
== 杂项信息 ==
=== 调式信息 ===
*永远不要提交无用的调式信息*
你加的调式信息对你来说是有用的,但是对别人来讲他是很糟糕的,每次运行打印一大堆无用的信息很令人反感同时影响效率.
=== 注释代码块 ===
我们不允许注释代码块上传,无用的代码就直接将他去掉,SVN等版本记录时能还原以前的代码的,千万要小心#if 0 #enfif注释代码
因为你随便调式注释会给别人带来麻烦,项目中遇到过很多次这种问题,以为是出现了bug,但是花半天调式后发现是xx把某代码注释起来了
这实在令人抓狂.
== 结束语 ==
运用常识和判断力, 并保持代码风格一致.
编辑代码时, 花点时间看看项目中的其它代码, 并熟悉其风格. 如果其它代码中 if 语句使用空格, 那么你也要使用. 如果其中的注释用星号 (*) 围成一个盒子状, 你同样要这么做.
风格指南的重点在于提供一个通用的编程规范, 这样大家可以把精力集中在实现内容而不是表现形式上. 我们展示了全局的风格规范, 但局部风格也很重要, 如果你在一个文件中新加的代码和原有代码风格相去甚远, 这就破坏了文件本身的整体美观, 也影响阅读, 所以要尽量避免.