您的位置:首页 > 编程语言 > C语言/C++

谷歌C++风格的一些摘抄

2014-10-25 11:33 162 查看
全部来源于网络,我感觉好的就复制粘贴了。

【你必需防止头文件重复编译。】

<PROJECT>_<PATH>_<FILE>_H_

foo/src/bar/baz.h => #ifndef FOO_BAR_BAZ_H_

【inline函数要尽量简单。】

函数最好小于10行。

函数内包含循环、switch语句,不能定义为inline。

过长inline函数体放在inl.h文件中。

【include的顺序】

当前c文件对应的头文件->C语言系统文件->C++系统文件->第三方库头文件->工程公用头文件。

【尽量减少头文件的引用,使用前置声明。】

【空格替换Tab,每次缩进2个空格。】

【你每行代码的文本最多只允许80个字符宽。】

【要少用非ASCII字符,即使用的话也必须用UTF-8格式。】

【空的循环体应该用{}或continue,而不是单独的一个分号。】

【不要用不必要的括号括起返回表达式。】

【预处理指令应该总在行首,不要缩进。】

【定义一个函数时,参数顺序是:输入参数,然后是输出参数。】

【一个类可以被定义在另一个类内,它也被称为成员类。】

class Foo {

private:

// Bar is a member class, nested within Foo.Bar是Foo中嵌套的成员类。

class Bar {

...

};

};

【你的类的定义应该从公开成员部分开始,接着是受保护成员,最后是私有成员。如果哪部分是空的就省略掉。】

类中各部分按public、protected和private的顺序,每个关键字缩进1个空格。

在每部分中,声明通常应该按下面的顺序排列:

1. 自定义别名和枚举

2. 常量(静态常量)

3. 构造函数

4. 析构函数

5. 方法,包括静态方法

6. 数据成员(除了静态常量成员)

【所有按引用传递的参数必须被标记为常量。】

在C中,如果一个函数需要修改一个变量,就必须使用指针参数。

【我们不使用C++的异常。】

(我并不认同,不过它的优点写得不错)

优点:

1. 异常允许上层应用程序决定如何处理底层嵌套函数出现的“不该发生“的错误,而不是用模糊且易错的错误码记录 。

2. 大数数其它现代语言中都包含异常。在C++中使用异常有助于保持与Python、Java和其它与C++类似的语言的兼容。

3. 一些第三方C++库使用异常,如果禁用异常的话就很难与这些库整合了。

4. 异常是处理构造函数失败的唯一方法。我们能用工厂函数或Init()来模拟这个特性,但这些分别需要进行堆的分配或是新增一个“无效”状态。

5. 在测试框架内异常很容易使用。

【避免使用RTTI。】

【不要使用C风格的转换。改用C++风格的转换。】

1. 用static_cast进行数值转换,或是显式的将一个类的指针转为它的子类的指针。

2. 用const_cast去掉常量性质。

3. 用reinterpret_cast进行不安全的指针间转换或整型转指针操作。只有在你清楚操作的含义及可能的后果时才能使用这种转换。

【一个变量在自加(++i或i++)或自减(--i或i--),而没有用到表达式的值时,必须确定到底用哪种形式。】

【能用常量的时候都要用常量。】

【C++的内建整数类型中,只使用int。如果程序中需要用到其它大小的变量,用<stdint.h>中带精度的整数类型,如int16_t。】

整型类型中,只有int可以用。合适的话,你最好用标准类型,如size_t和ptrdiff_t。

我们经常用int,用在不会特别大的整数上,如循环计数器。这时要用POD类型int。你应该假设int至少有32位,但不要假设它超过32位。如果你需要用64位整数,就用int64_t或uint64_t。

对于可能会很大的整数,用int64_t。

你不应该用无符号整型,如uint32_t,除非你在表示一个位组而不是数字,或是你需要定义二进制补码溢出。尤其是,不要为了指出数值永不为负而使用无符号数。你应该用断言。

【不要用无符号数。】

糟糕的bug会在有符号数和无符号数比较时发生。

所以,用断言来提醒变量是非负的。不要用无符号类型。

【代码应该同时兼容32位和64位。要考虑到打印、比较、以及结构体对齐等问题。】

【用内联函数、枚举量、和常量来代替宏。】

使用宏就意味着你看到的代码和编译器最终看到的代码是不一样的。这会带来难以预料的行为,特别是因为宏是全局作用域生效的。

不要用宏来展开性能要求高的代码,改用内联函数。不要用宏来存储一个常数,改用常量。不要用宏来为一个名字很长的变量起个较短的别名,改用引用。不要用宏来进行条件编译,改用……好吧,不要进行条件编译(除非是用#define来避免多次引入头文件)。用宏会导致很难进行测试。

下面的使用模式能避免使用宏会带来的很多问题;如果你要用宏,就要尽量遵循这些准则:

1. 不要在.h文件中定义宏。

2. 在马上要用到宏的地方才#define宏,用完立刻#undef。

3. 不要#undef一个现有的宏,仅仅因为自己的宏要用它的名字;不如为自己的宏取一个独特的名字。

4. 不要用那些展开后会导致C++构造不稳定的宏,如果非要用,就在文档中说明。

5. 不推荐使用##生成函数/类/变量的名字。

【0用于整数,0.0用于浮点数,nullptr用于指针,’\0’用于字符。】

【在可以的地方用sizeof(变量名)来代替sizeof(类型名)。】

用sizeof(变量名)是因为如果变量的类型改变了,它也能跟着更新。sizeof(类型名)在一些场合更有意义,但还是要避免这么用,因为变量类型改变后它没有跟着同步改变。

【不要在局部变量之外的地方用auto。】

程序员需要懂得auto和const auto&间的区别,否则会在不想复制时出现复制。

【只用Boost库集中被认可的部分。】

元模板编程虽然很装逼,但是要记得,你不是一个人。

【只使用C++11(也称为C++0x)中被认可的库和语言扩展。在用C++11特性前先考虑一下可移植性。】

只用C++11中被认可的库和语言特性。当前只认可下列特性:

1. auto(只用于局部变量)。

2. “>>”现在优先匹配模板参数表的结束,而不是输出操作符。

3. 以范围为基础的 for 循环。

4. 整数字面值+LL和ULL后缀以产生不少于64位的类型。

5. 可变参数宏(但注意不鼓励用宏)。

6. 所有声明于<algorithm>和<numeric>中的新STL算法,除了声明中包含初始化列表的min、max和minmax版本。

7. 用局部类型充当模板参数 。

8. nullptr和nullptr_t。

【永远不要用省略字母的缩写。】

int error_count; // Good.

int error_cnt; // Bad.

【文件名应该全都用小写,中间用“-”或“_”当分隔符。根据你的项目的惯例。如果没有固定的习惯的话,推荐用“_”。】

【C++文件应该以.cc结尾,头文件以.h结尾。】

【类型名以大写字母开头(包含typedef),且其中每个词第一个字母都大写,不用下划线:MyExcitingClass,MyExcitingEnum。】

【变量名都是小写的,每个词之间用下划线连接。类的成员变量名结尾有个下划线。例如:my_exciting_local_varialbe;my_exciting_member_variable_。】

string table_name; // OK - uses underscore.

string tablename; // OK - all lowercase.

string tableName; // Bad - mixed case.

【(类)数据成员(也被称为实例变量或成员变量)的名字都是小写的,可以像通常的变量名一样带下划线,但结尾总要有个下划线。】

string table_name_; // OK - underscore at end.

string tablename_; // OK.

【对于全局变量没有特别要求,少用就好,但如果你要用,考虑加个g_前缀,或其它能很容易的区分全局变量与局部变量的标记。】

【常规函数的名字大小写混合;取值和设值函数要与对应的变量名匹配:MyExcitingFunction(),MyExcitingMethod(),my_exciting_member_variable(),set_my_exciting_member_variable()。】

【注释:每个文件的开始是版权公告,其后是文件内容描述。】

每个文件都应包括许可证信息。为项目选择适合的许可证版本(如Apache2.0、BSD、LGPL、GPL)。

【如果你习惯了通行的Windows风格,就很有必要重申一些你可能忘记的规范:】

1. 不要用匈牙利命名法(例如将整数命名为iNum)。用谷歌的命名规范,源代码文件扩展名用.cc。

2. Windows定义了许多它独有的内置类型的别名,如DWORD和HANDLE等等。在你调用Windows API时鼓励用这些类型。即使这样,你也应该尽量使用C++的类型名。例如,用constTCHAR*去替代LPCTSTR。

3. 用VC++编译代码时,将警告等级调到3或更高,并将所有警告都视作错误。

4. 不要用#pragma once;改用标准的头文件守卫规则。在#define中的路径要相对于项目根目录。

5. 事实上不要用任何不标准的编译器扩展,如#pragma和__declspec,除非你必须得这么做。用__declspec(dllimport)和__declspec(dllexport)是允许的;但你必须通过宏来调用它们,如DLLIMPORT和DLLEXPORT, 这样别人就可以在分享使用此代码时方便的禁用这些扩展了。

【但是,在Windows中还是有些场合我们必须打破某些规则:】

1. 通常我们禁止使用多个有实现的继承;但在用COM和一些ATL/WTL类时需要这么做。这时你就可以使用多个有实现的继承了。

2. 尽管你不应该在自己的代码中用到异常,但异常被广泛用在ATL和一些VC++的STL实现中。用ATL时,你应该定义_ATL_NO_EXCEPTIONS来禁用异常。你应该研究一下是否也可以禁用STL中的异常,如果不能的话启用异常也没关系。(注意这只是为了编译STL,自己的代码中仍然不允许用异常。)

3. Windows代码文件中通常都包括预编译好的头文件stdafx.h或precompile.h。为了让你的代码方便与其它项目分享,避免显式include此文件(除了precompile.cc),用/FI编译选项来自动包括此文件。

4. 资源头文件通常被命名为resource.h且只包括宏,不需要遵守这些风格规范。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: