C++编程风格1——头文件

来源:互联网 发布:约瑟夫环算法 编辑:程序博客网 时间:2024/05/17 19:20

1、防文件重复包含

方法1:Window平台下,有专门的命令#pragma once防止头文件重复包含

方法2:

#ifndef XXX_H//通用的的防头文件重复的命令,如test.h可以写成TEST_H
#define XXX_H

……

#endif

2、前置声明(forward declarations)

使用前置声明尽量减少.h文件中#include的数量

  当一个头文件被包含的同时也引入了一项新的依赖,叧要该头文件被修改,代码就要重新编译。如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那些包含了你的头文件的代码重新编译。因此,我们应该尽量少的包含头文件,尤其是那些包含在其他头文件中的。

使用前置前场可以显著减少需要包含的头文件数量。举例说明:头文件中用到类File,但不需要访问File的声明,则头文件中只需前置声明class File;无需#include "file/base/file.h"。

假如我们遇到这种情况,当定义一个类 class A,这个类里面使用了类B的对象b,然后定义了一个类B,里面也包含了一个类A的对象a,就成了这样:

//a.h文件#include "b.h"  class A  {  ....  private:      B b;  };  //b.h文件  #include "a.h"  class B  {  ....  private:      A a;  };  
一编译,就出现了一个互包含的问题了,这时就有人跳出来说,这个问题的解决办法可以这样,在a.h文件中声明类B,然后使用B的指针。
//a.h   //#include "b.h"  class B;   class A   {   ....   private:   B b;   };   //b.h   #include "a.h"   class B  {   ....   private:   A a;   };  

上面用到的就是先置声明,在前置声明时,我们只能使用的就是类的指针和引用(因为引用也是居于指针的实现的)。前置声明的另外一个好处是减小类A的大小。那么,这里有个问题:为什么我们前置声明时,只能使用类型的指针和引用呢?
如果你回答到:那是因为指针是固定大小,并且可以表示任意的类型,另一个原因是只要这个声明没有执行需要了解类A的大小或者成员的操作就可以了,所以声明成指针或引用是没有执行需要了解类A的大小或者成员的操作的

不过这里还有几个要注意的错误不能犯:

1)B* b;必须用指针或引用
2)不能在类A的声明中使用类B的方法
3)在类B定义之前调用类B的析构函数

3、内联函数

当函数叧有 10 行甚至更少时才会将其定义为内联函数(inline function)。优点:当函数体比较小的时候,内联该函数可以令目标代码更加高效。对于存放函数(accessor、 mutator)以及其他一些比较短的关键执行函数。能够减少函数的调用时间,只适用于简单函数,一个比较得当的处理原则是,不要内联超过 10 行的函数。对于析构函数应慎重对待,析构函数往往比其表面看起来要长,因为有一些隐式成员和基类析构函数(如果有的话)被调用!

另外,1.递归函数不能定义为内联函数
 2.内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
 3.内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
 4.对内联函数不能进行异常的接口声明。
4.-ini.h文件

复杂的内联函数的定义,应放在后缀名为-ini.h的头文件中。

5、函数参数顺序(Function Parameter Ordering)

定义函数时,参数顺序为:输入参数在前,输出参数在后。

6、包含文件的名称及次序

将包含次序标准化可增强可读性、避免隐藏依赖(hidden dependencies,注:隐藏依赖主要是指包含的文件编译),次序如下:C 库、 C++库、其他库的.h、项目内的.h。
具体的例子是:假如你有一个cc文件(linux平台的cpp文件后缀为cc)是google-awesome-project/src/foo/internal/fooserver.cc,那么它所包含的头文件的顺序如下:

#include "foo/public/fooserver.h"  // Preferred location.C<span style="white-space:pre"></span>cc文件的头文件#include <sys/types.h>#include <unistd.h><span style="white-space:pre"></span>//C系统文件#include <hash_map><span style="white-space:pre"></span>//C++系统文件#include <vector>#include "base/basictypes.h"<span style="white-space:pre"></span>//其他库头文件#include "base/commandlineflags.h"<span style="white-space:pre"></span>//本项目自定义头文件#include "foo/public/bar.h"

另外,2. 在包含头文件时应该加上头文件所在工程的文件夹名,即假如你有这样一个工程base,里面有一个logging.h,那么外部包含这个头文件应该这样写:#include "base/logging.h",而不是#include "logging.h"

以上总结 :

1. 避免多重包含是学编程时最基本的要求;
2. 前置声明是为了降低编译依赖,防止修改一个头文件引发多米诺效应;
3. 内联函数的合理使用可提高代码执行效率;
4. -inl.h 可提高代码可读性(一般用到吧:D);
5. 标准化函数参数顺序可以提高可读性和易维护性(对函数参数的堆栈空间有轻微影响,我以前大多是相
同类型放在一起);
6.google的包含文件的顺序不是绝对有优势的,《C++编程风格》提出的另一种规则:头文件被包含的顺序是从“最特殊到最一般”。这就是,在本地目录的任何头文件首先被包含。然后是我们自己的所有“工具”头文件,随后是第三方库头文件,接着是标准C++库头文件和C库头文件。也有其优点,所以选哪一种看个人的编程习惯。






0 0
原创粉丝点击