设为首页 加入收藏

TOP

C++编码规范(Google C++ Style Guide)
2014-11-24 03:11:45 来源: 作者: 【 】 浏览:1
Tags:编码 规范 Google Style Guide

I 关于编码规范


1.最重要的一点:明确规范,然后保持一致。BE CONSISTENT!


II Header Files


1.The #define Guard


Guard的命名规则为___H_。比如foo工程中的文件foo/src/bar/baz.h应定义如下Guard:


2.头文件依赖


在头文件中尽量使用forward declaration替代#include,这样可以减少头文件之间的相互依赖,从而可能使得增量编译时需要重新编译的编译单元减少。


如果要在一个头文件中使用类Foo,则在以下情况下,可以仅使用forward declaration:


1)声明类型为Foo *或Foo &的数据成员。


2)声明参数或返回类型为Foo的函数。


3)声明类型为Foo的静态数据成员。因为静态数据成员是在类定义之外定义的。


如果在源文件(.cpp或.cc)中需要使用符号Foo,应该直接在源文件中使用#include引入Foo的定义,而不是依赖于其它头文件的间接包含。一个例外是,如果Foo在myfile.cc中使用,可以在myfile.h中包含相应头文件。


3.内联函数


只有在函数足够小时才定义内联函数,比如小于10行。


不要把析构函数声明为内联函数,因为析构函数往往比你编写的要长得多,因为编译器会插入相关成员的析构操作。


不要将函数有loop和switch的函数声明的内联函数。


有些函数即使声明为内联函数也不会内联,比如虚函数和递归函数。


4.The -inl.h Files


由于内联函数需要在头文件中实现,这样编译器才能在相应函数被调用的地方插入内联函数实现代码。


对于简单的内联函数,比如accessors和mutators,应该在.h文件中定义。


更复杂的内联函数应该在单独的-inl.h文件中定义。


使用-inl.h文件的另一种情况是函数模板的定义,从而使得你的模板定义更具可读性。


5.函数参数的顺序


C++的函数参数有三种类型:input, output, or both. 规则是将输入参数放在输出参数之前。


通常输入参数应该是值类型或const引用,输出参数是非const指针。


6.Names and Order of Includes


头文件应分组包含,通常以如下顺序包含头文件:类定义头文件,C库,C++库,其它三方库,工程定义头文件


所有工程定义的头文件,应该以工程源码根目录为起点,列出完整路径,绝不应该使用"."和".."来表示以当前目录为基准的相对路径。


例:


III Scoping



1.命名空间


命名空间定义结束时应使用注释标明对应的命名空间。


1.1 Unnamed namespaces


鼓励在.cc文件中使用Unnamed namespaces,这样可以防止运行时命名冲突。通常将局部于.cc文件的一些helper函数放在Unnamed namespace中。


绝不在.h文件中使用Unnamed namespace.


1.2 Named namespaces


在头文件和forward declarations之后,命名空间包含整个源文件。


绝不使用using指令导入整个命名空间,以免造成命名空间污染。可以使用using导入单个符号。


using指令可以出现在.cc文件中的任何位置,以及头文件的函数、方法和类中。


1.3 Namespace alias


命名空间别名可以出现在.cc文件中的任何位置,头文件中包含整个头文件的命名空间内,以及头文件中的函数和方法中。


如果在.h中使用了命名空间别名,则包含此头文件的文件也可以见到此别名,因此在头文件中使用命名空间别名应慎重。


2.嵌套类


不要使用public nested class,除非你确定它是接口的一部分。这种情况下直接定义这个类(不定义为嵌套类)通常更直观。更进一步,可以使用命令空间来达到将这个类和全局作用域隔离的目的。


3.Nonmember, Static Member, and Global Functions


有一些函数不属于任何类或者不适合作为某个类的成员,则最好的处理方式是将其定义为非成员函数,并声明一个命名空间来管理这些函数。不要仅为了组织一组函数而定义一个类。


如果这些函数只在当前.cc文件中使用,则可以使用unnamed namespace或者声明为static linkage。


如果这些函数共享某些静态数据,则应该将它们定义为一个新的类的静态成员函数。


尽量不使用全局函数。


4.局部变量


让局部变量的作用域尽可能小,并且在定义的时候初始化,而不是先定义再赋值


应该在使用变量之前才定义变量,不使用以前C风格的在函数一开始定义所有局部变量的方式。



5.静态变量和全局变量


绝不使用类类型的静态变量或全局变量,因为对象创建和销毁顺序的不确定性往往造成难以发现的bug


具有静态存储 (static storage duration)的对象,包括静态变量、全局变量、类的静态成员变量和函数内的静态变量,都应该是“平凡数据对象 (POD, Plain Old Data)”:ints, chars, floats, 指针或者以 POD为元素的arrays/structs 。


C++规范没有完备地说明静态成员初始化式的调用顺序,因此不要用函数调用来初始化静态POD变量,除非调用的函数不依赖于其它全局的东西。


对象的销毁顺序与创建顺序相反,因为创建顺序不确定,所以销毁的顺序也是不确定的(例如,在程序结束时,一个静态变量可能已经被销毁了,但是代码依然在执行(可能在另一个线程中)并且试图访问这个静态变量)。结果是静态变量只允许为POD,这一规则完全排除了将vector(使用C风格数组)和string(使用const char[])作为静态变量使用。


如果一定要将一个类对象作为静态或全局的,应该使用指针(不会被释放),然后在main函数初始化(或者使用pthread_once()初始化)。要注意这个指针应该是“平凡”的指针(raw pointer),而不是智能指针(smart pointer)。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux系统编程之错误处理:perror.. 下一篇C++标准程序库 - 模板基础

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C++ 语言社区-CSDN社 (2025-12-24 17:48:24)
·CSDN问答专区社区-CS (2025-12-24 17:48:22)
·C++中`a = b = c`与` (2025-12-24 17:48:19)
·C语言结构体怎么直接 (2025-12-24 17:19:44)
·为什么指针作为c语言 (2025-12-24 17:19:41)