- 浏览: 901304 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yaawaas:
有了 。。
程序员装B指南 -
niepeng880208:
藐视我还是初级装
程序员装B指南 -
sa364867195:
哥们,现在实现了吗?
GPS卫星定位车辆监控系统 -
月下小人:
顶,这才是质的提高,果断顶
一个基于jQuery ajax和.net httphandler 的超轻异步框架,千行代码完成。 -
xp9802:
有意思,动静结合
程序员装B指南
Felomeng翻译:Google C++ 编程规范——头文件收藏 function change_alt1(btn,style){var btn=document.getElementById(btn);btn.style.display = style;}此文于2011-03-22被推荐到CSDN首页如何被推荐?
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""><span style="font-size: small;"><span style="color: #ff0000;">与官方翻译版本(<a href="http://code.google.com/p/zh-google-styleguide/downloads/list">http://code.google.com/p/zh-google-styleguide/downloads/list</a>)不同,本文为本人原创翻译。 </span></span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""><span style="font-size: small;">一般地,</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">.cc</span><a style="" name="_ftnref1" href="#_ftn1"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[1]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">文件都有一个对应的</span><span lang="EN-US"><span style="font-family: Times New Roman;">.h</span></span><span style="">文件。但是有一些常见的例外情况,比如单元测试和只含有</span><span lang="EN-US"><span style="font-family: Times New Roman;">main()</span></span><span style="">函数的小型源文件。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">头文件的正确运用,可以极大地提高代码的可读性,控制代码的规模和提高软件的性能。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">下列规则有助于避免头文件使用中容易产生的诸多错误。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946439"></a><a name="The__define_Guard"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.1</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">利用</span><span lang="EN-US"><span style="font-family: Cambria;"> #define</span></span></span></strong></span></a><strong><span style="font-size: large;"><span style="">防止多重包含</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">头文件应该使用</span><span lang="EN-US"><span style="font-family: Times New Roman;">#define</span></span><span style="">定义预编译标识符来标识当前头文件,以来避免多重包含。标识符命名规则是:</span><span lang="EN-US"><span style="font-family: Times New Roman;">[</span></span><span style="">项目名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_[</span></span><span style="">路径名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_[</span></span><span style="">文件名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_H_</span></span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">为了保证唯一性,标识符应当以头文件在项目中的全路径来命令。例如,在项目</span><span lang="EN-US"><span style="font-family: Times New Roman;">foo</span></span><span style="">中的文件</span><span lang="EN-US"><span style="font-family: Times New Roman;">foo/src/bar/baz.h</span></span><span style="">应该通过下面代码来进行保护:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#ifndef FOO_BAR_BAZ_H_</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#define FOO_BAR_BAZ_H_</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">...</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#endif<span style=""> </span>// FOO_BAR_BAZ_H_</span></p>
</div>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946440"></a><a name="Header_File_Dependencies"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.2</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">头文件依赖</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">可以使用前置声明时,就不要使用</span><span style="" lang="EN-US">#include</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">源代码文件中包含一个头文件就形成了一个新的依赖关系,一旦修改此头文件,就得重新编译源代码文件。如果某个头文件中包含了别的头文件,那么修改任何一个头文件,都得重新编译包含这个头文件的源代码文件。因此,要尽量减少包含关系,尤其是头文件的相互包含。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">在头文件中使用前置声明,可以有效减少头文件中包含头文件的数量。例如,头文件中要使用</span><span style="" lang="EN-US">File</span><span style="">类,但是却用不到</span><span style="" lang="EN-US">File</span><span style="">类的声明。这时可以不包含</span><span style="" lang="EN-US">File</span><span style="">类的头文件(</span><span style="" lang="EN-US">#include “file/base/file.h”</span><span style="">),只要使用前置声明来声明类</span><span style="" lang="EN-US">File</span><span style="">就可以了。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">那么,怎样才能在不使用类</span><span style="" lang="EN-US">Foo</span><span style="">的定义就可以使用类</span><span lang="EN-US"><span style="font-family: Times New Roman;">Foo</span></span><span style="">呢?可以这样:</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明数据成员类型</span><span style="" lang="EN-US">Foo*</span><span style="">或</span><span style="" lang="EN-US">Foo&</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明类</span><span style="" lang="EN-US">Foo</span><span style="">的函数及其参数,甚至包括返回值。(这里有一个例外,就是当变量</span><span style="" lang="EN-US">Foo</span><span style="">或</span><span style="" lang="EN-US">const Foo&</span><span style="">具有单参数隐式转换的构造函数时,就需要类的完整声明来支持自动类型转换)</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明类</span><span style="" lang="EN-US">Foo</span><span style="">的静态数据成员变量。因为静态数据成员的定义不包含在类定义之内。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">但是,如果你要继承</span><span style="" lang="EN-US">Foo</span><span style="">类或者有成员变量是</span><span style="" lang="EN-US">Foo</span><span style="">类型,则必须引用</span><span style="" lang="EN-US">Foo</span><span style="">类的头文件。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">有时,可以使用指针(</span><span style="" lang="EN-US">scoped_ptr</span><span style="">更佳)来代替对象作为成员变量。但是,这将影响代码可读性并降低程序执行效率。因此,如果仅是出于减少包含头文件数量的考虑,就不要这么做了。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">当然,</span><span style="" lang="EN-US">.cc</span><span style="">文件通常需要所有类的定义,因此需要包含多个头文件。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">提示:</span></strong><span style="">如果要在在源代码文件中使用</span><span style="" lang="EN-US">Foo</span><span style="">,则应当主动通过</span><span lang="EN-US"><span style="font-family: Times New Roman;">#include</span></span><span style="">或前置声明引入</span><span style="" lang="EN-US">Foo</span><span style="">的定义。不要依赖于传递关系包含的头文件。例外情况:如果</span><span style="" lang="EN-US">Foo</span><span style="">在</span><span style="" lang="EN-US">myfile.cc</span><span style="">文件中使用,则可以在</span><span style="" lang="EN-US">myfile.h</span><span style="">文件(而不是文件</span><span style="" lang="EN-US">myfile.cc</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">)中包含(或前置声明)类</span><span style="" lang="EN-US">Foo</span><span style="">。</span></span></p>
<p class="Heading2ForEnglish" style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.3</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">内联函数</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">只有当函数体足够小时(不多于十行)才使用内联函数。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">定义:</span></strong><span style="">内联函数与普通函数不同,不需要经过函数调用机制来调用。在编译内联函数时,编译器是先把内联函数体内的代码拷贝到调用内联函数的位置(这个过程称为内联展开),替换原有的调用语句,然后再编译。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">优点:</span></strong><span style="">函数体较小时,使用内联方式可以提升程序执行效率。对于取值函数</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">(accessor)</span><a style="" name="_ftnref2" href="#_ftn2"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[2]</span></span></span></span></span></a></span><span style=""><span style="font-size: small;">、赋值函数</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">(mutator)</span><a style="" name="_ftnref3" href="#_ftn3"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[3]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">,以及所有函数体短小而又要求高执行效率的函数,都应当声明为内联函数。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">劣势:</span></strong><span style="">内联函数的滥用将导致程序运行缓慢。使用内联方式可能会增大或减小程序的体积,这与函数体本身的大小有关。将函数体很小的取值函数声明为内联方式,通常会减小程序体积;而将一个比较大的函数声明为内联方式,则将明显增大程序体积。另一方面,在现代处理器上,短代码运行效率优于老式处理器,因为现代处理器有更好的指令缓存机制(因此,无须使用内联函数)。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style=""><span style="">结论</span>:</span></strong></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">一个比较好的规则就是当函数代码多于</span><span lang="EN-US"><span style="font-family: Times New Roman;">10</span></span><span style="">行时,就不使用内联方式。要特别注意析构函数,它们的实际代码行数很可能大于看到的行数,因为析构函数中可能会隐含成员,还可能会包括父类的析构函数!</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">另一个好的规则是,具有循环体或分支(</span><span lang="EN-US"><span style="font-family: Times New Roman;">switch</span></span><span style="">语句)结构的函数,不宜内联(除非这些循环或分支语句一般不会被执行)。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">即使声明为内联函数,也不一定会被编译为内联函数,这一点很重要。比如虚函数和递归函数一般就不会编译为内联函数。通常,递归函数不应声明为内联函数。将虚函数声明为内联的主要是为了方便或者在文档中说明它的功能(比如取值和赋值函数)。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946442"></a><a name="The_-inl.h_Files"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.4</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">以</span><span lang="EN-US"><span style="font-family: Cambria;">inl.h</span></span></span></strong></span></a><strong><span style="font-size: large;"><span style="">为后缀的文件</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">复杂内联函数,应当在以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件中进行定义。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">内联函数的定义需要放在头文件内,这样编译器才可以在调用处将其内联展开。但是,实现代码应当放在</span><span style="" lang="EN-US">.cc</span><span style="">文件当中,除非可以提高可读性或运行效率,否则不应该把太多实现代码放在</span><span style="" lang="EN-US">.h</span><span style="">文件中。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">如果内联函数足够短小(只含有极少或是没有逻辑语句),则应该将内联函数放进</span><span style="" lang="EN-US">.h</span><span style="">文件。比如,取值函数和赋值函数就应当放在类的定义里面。为了实现和调用的方便,更复杂的内联函数也应当定义在</span><span style="" lang="EN-US">.h</span><span style="">文件中。如果这样做影响到了代码的可读性,那么可以将这些内联函数放进一个单独的头文件(以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀)。这样可以把内联函数的实现与类定义分开,同时,又不影响在别处包含内联函数实现。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件的另一个用途是用来定义函数模板。这样做可以提高模板定义的可读性。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">别忘了,与别的头文件一样,</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件同样应当</span><span lang="EN-US"><a href="#The__define_Guard"><span style="color: #0000ff;"><span style="" lang="EN-US"><span lang="EN-US">利用</span></span><span style="font-family: Times New Roman;"> #define</span><span style="" lang="EN-US"><span lang="EN-US">防止多重包含</span></span></span></a></span><span style="">。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946443"></a><a name="Function_Parameter_Ordering"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.5</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">函数参数排序</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">定义函数时,参数的顺序应为:输入参数在前,输出参数在后。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C/C++</span></span><span style="">语言中函数的参数分为输入参数与输出参数,也可以既是输入又是输出参数(简称为输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数)。输入参数通常是值类型或者<span style="color: #00b050;">常</span>引用类型,而输出参数与输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数则为非<span style="color: #00b050;">常</span>指针。参数排序时,输入参数应排在其他参数前面。特别地,不能因为参数是新添加的而简单地将参数排到最后,要把新的输入参数排在输出参数前面。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">这条规则并不要求严格遵守。因为输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数(通常是类或结构体)很特别,会影响到这条规则。有时为了保持与相关函数的一致性,则不得不违反这条规则。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946444"></a><a name="Names_and_Order_of_Includes"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.6</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">文件包含的名称与次数</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""><span style="font-size: small;">为了可读性并避免隐性依赖(</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">hidden dependencies</span><a style="" name="_ftnref4" href="#_ftn4"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[4]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">),包含头文件的顺序应当遵循这样的标准:</span><span lang="EN-US"><span style="font-family: Times New Roman;">C</span></span><span style="">库文件,</span><span lang="EN-US"><span style="font-family: Times New Roman;">C++</span></span><span style="">库文件,其他的库文件</span><span style="" lang="EN-US">.h</span><span style="">,本工程中的库文件</span><span style="" lang="EN-US">.h</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">项目中定义的头文件,都应该放在项目源文件夹中,并且包含语句中不应当含有</span><span lang="EN-US"><span style="font-family: Times New Roman;">UNIX</span></span><span style="">文件夹缩写符号“</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">”(表示当前文件夹),或“</span><span lang="EN-US"><span style="font-family: Times New Roman;">..</span></span><span style="">”(表示上一级文件夹)。例如,</span><span style="" lang="EN-US">google-awesome-project/src/base/logging.h</span><span style="">应当使用这样的包含语句:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/logging.h"</span></p>
</div>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">如果文件</span><em><span style="" lang="EN-US">dir/foo</span></em><span style="" lang="EN-US">.cc</span><span style="">主要用来测试</span><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="">,则应这样排列头文件包含顺序:</span></span></p>
<p class="a" style="text-indent: 24pt; margin: 6pt 0cm;"><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="font-size: small;"><span style="">(优先排序——下面会详细说明原因)</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C</span></span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C++</span></span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">其他</span><span style="" lang="EN-US">.h</span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">当前项目</span><span style="" lang="EN-US">.h</span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">优先排序可以减少隐性依赖。每个头文件都应该能独立编译。要达到这样的效果,最简单的方法就是让这些头文件作为</span><span style="" lang="EN-US">.cc</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">文件中使用</span><span style="" lang="EN-US">#include</span><span style="">语句包含的第一个</span><span style="" lang="EN-US">.h</span><span style="">文件。</span></span></p>
<p class="a" style="text-indent: 24pt; margin: 6pt 0cm;"><em><span style="" lang="EN-US">dir/foo</span></em><span style="" lang="EN-US">.cc</span><span style="font-size: small;"><span style="">和</span><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="">通常在同一文件夹下(比如,</span><span style="" lang="EN-US">base/basictypes_test.cc</span><span style="">和</span><span style="" lang="EN-US">base/basictypes.h</span><span style="">),但也可以在不同的文件夹下。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">每个库的包含语句,最好按字母顺序排序。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">例如,</span><span style="" lang="EN-US">google-awesome-project/src/foo/internal/fooserver.cc</span><span style="">中的包含语句可以是这样的:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "foo/public/fooserver.h"<span style=""> </span>// Preferred location.</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <sys/types.h></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <unistd.h></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <hash_map></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <vector></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/basictypes.h"</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/commandlineflags.h"</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "foo/public/bar.h"</span></p>
</div>
<div style="">
<br><hr size="1">
<div id="ftn1" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn1" href="#_ftnref1"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[1]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">Linux/Unix</span></span><span style="">下</span><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">源代码文件的扩展名,与</span><span lang="EN-US"><span style="font-family: Calibri;">.cpp</span></span><span style="">等同</span></p>
</div>
<div id="ftn2" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn2" href="#_ftnref2"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[2]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">accessor </span></span><span style="">原意是:函数名以</span><span lang="EN-US"><span style="font-family: Calibri;">get</span></span><span style="">(获取)开头,以要获取的变量名结束,返回值的类型就是要获取变量的类型。故,此处译为取值函数</span></p>
</div>
<div id="ftn3" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn3" href="#_ftnref3"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[3]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">mutator</span></span><span style="">原意是:可以修改某个成员变量值的函数,通常指通过一定计算修改某成员变量值的函数(多数情况下就是直接把某个值赋给成员变量)。其实,除了常函数外,所有函数都可以称为</span><span lang="EN-US"><span style="font-family: Calibri;">mutator</span></span><span style="">。故,此处译为赋值函数。</span></p>
</div>
<div id="ftn4" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn4" href="#_ftnref4"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[4]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:隐性依赖是指两个看似相互独立的组件具有的某种关联,这种关联通常由第三方组件中的数据流引起。</span></p>
</div>
</div>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""><span style="font-size: small;">一般地,</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">.cc</span><a style="" name="_ftnref1" href="#_ftn1"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[1]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">文件都有一个对应的</span><span lang="EN-US"><span style="font-family: Times New Roman;">.h</span></span><span style="">文件。但是有一些常见的例外情况,比如单元测试和只含有</span><span lang="EN-US"><span style="font-family: Times New Roman;">main()</span></span><span style="">函数的小型源文件。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">头文件的正确运用,可以极大地提高代码的可读性,控制代码的规模和提高软件的性能。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">下列规则有助于避免头文件使用中容易产生的诸多错误。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946439"></a><a name="The__define_Guard"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.1</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">利用</span><span lang="EN-US"><span style="font-family: Cambria;"> #define</span></span></span></strong></span></a><strong><span style="font-size: large;"><span style="">防止多重包含</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">头文件应该使用</span><span lang="EN-US"><span style="font-family: Times New Roman;">#define</span></span><span style="">定义预编译标识符来标识当前头文件,以来避免多重包含。标识符命名规则是:</span><span lang="EN-US"><span style="font-family: Times New Roman;">[</span></span><span style="">项目名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_[</span></span><span style="">路径名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_[</span></span><span style="">文件名</span><span lang="EN-US"><span style="font-family: Times New Roman;">]_H_</span></span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">为了保证唯一性,标识符应当以头文件在项目中的全路径来命令。例如,在项目</span><span lang="EN-US"><span style="font-family: Times New Roman;">foo</span></span><span style="">中的文件</span><span lang="EN-US"><span style="font-family: Times New Roman;">foo/src/bar/baz.h</span></span><span style="">应该通过下面代码来进行保护:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#ifndef FOO_BAR_BAZ_H_</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#define FOO_BAR_BAZ_H_</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">...</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#endif<span style=""> </span>// FOO_BAR_BAZ_H_</span></p>
</div>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946440"></a><a name="Header_File_Dependencies"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.2</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">头文件依赖</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">可以使用前置声明时,就不要使用</span><span style="" lang="EN-US">#include</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">源代码文件中包含一个头文件就形成了一个新的依赖关系,一旦修改此头文件,就得重新编译源代码文件。如果某个头文件中包含了别的头文件,那么修改任何一个头文件,都得重新编译包含这个头文件的源代码文件。因此,要尽量减少包含关系,尤其是头文件的相互包含。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">在头文件中使用前置声明,可以有效减少头文件中包含头文件的数量。例如,头文件中要使用</span><span style="" lang="EN-US">File</span><span style="">类,但是却用不到</span><span style="" lang="EN-US">File</span><span style="">类的声明。这时可以不包含</span><span style="" lang="EN-US">File</span><span style="">类的头文件(</span><span style="" lang="EN-US">#include “file/base/file.h”</span><span style="">),只要使用前置声明来声明类</span><span style="" lang="EN-US">File</span><span style="">就可以了。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">那么,怎样才能在不使用类</span><span style="" lang="EN-US">Foo</span><span style="">的定义就可以使用类</span><span lang="EN-US"><span style="font-family: Times New Roman;">Foo</span></span><span style="">呢?可以这样:</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明数据成员类型</span><span style="" lang="EN-US">Foo*</span><span style="">或</span><span style="" lang="EN-US">Foo&</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明类</span><span style="" lang="EN-US">Foo</span><span style="">的函数及其参数,甚至包括返回值。(这里有一个例外,就是当变量</span><span style="" lang="EN-US">Foo</span><span style="">或</span><span style="" lang="EN-US">const Foo&</span><span style="">具有单参数隐式转换的构造函数时,就需要类的完整声明来支持自动类型转换)</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">声明类</span><span style="" lang="EN-US">Foo</span><span style="">的静态数据成员变量。因为静态数据成员的定义不包含在类定义之内。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">但是,如果你要继承</span><span style="" lang="EN-US">Foo</span><span style="">类或者有成员变量是</span><span style="" lang="EN-US">Foo</span><span style="">类型,则必须引用</span><span style="" lang="EN-US">Foo</span><span style="">类的头文件。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">有时,可以使用指针(</span><span style="" lang="EN-US">scoped_ptr</span><span style="">更佳)来代替对象作为成员变量。但是,这将影响代码可读性并降低程序执行效率。因此,如果仅是出于减少包含头文件数量的考虑,就不要这么做了。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">当然,</span><span style="" lang="EN-US">.cc</span><span style="">文件通常需要所有类的定义,因此需要包含多个头文件。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">提示:</span></strong><span style="">如果要在在源代码文件中使用</span><span style="" lang="EN-US">Foo</span><span style="">,则应当主动通过</span><span lang="EN-US"><span style="font-family: Times New Roman;">#include</span></span><span style="">或前置声明引入</span><span style="" lang="EN-US">Foo</span><span style="">的定义。不要依赖于传递关系包含的头文件。例外情况:如果</span><span style="" lang="EN-US">Foo</span><span style="">在</span><span style="" lang="EN-US">myfile.cc</span><span style="">文件中使用,则可以在</span><span style="" lang="EN-US">myfile.h</span><span style="">文件(而不是文件</span><span style="" lang="EN-US">myfile.cc</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">)中包含(或前置声明)类</span><span style="" lang="EN-US">Foo</span><span style="">。</span></span></p>
<p class="Heading2ForEnglish" style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.3</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">内联函数</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">只有当函数体足够小时(不多于十行)才使用内联函数。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">定义:</span></strong><span style="">内联函数与普通函数不同,不需要经过函数调用机制来调用。在编译内联函数时,编译器是先把内联函数体内的代码拷贝到调用内联函数的位置(这个过程称为内联展开),替换原有的调用语句,然后再编译。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">优点:</span></strong><span style="">函数体较小时,使用内联方式可以提升程序执行效率。对于取值函数</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">(accessor)</span><a style="" name="_ftnref2" href="#_ftn2"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[2]</span></span></span></span></span></a></span><span style=""><span style="font-size: small;">、赋值函数</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">(mutator)</span><a style="" name="_ftnref3" href="#_ftn3"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[3]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">,以及所有函数体短小而又要求高执行效率的函数,都应当声明为内联函数。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style="">劣势:</span></strong><span style="">内联函数的滥用将导致程序运行缓慢。使用内联方式可能会增大或减小程序的体积,这与函数体本身的大小有关。将函数体很小的取值函数声明为内联方式,通常会减小程序体积;而将一个比较大的函数声明为内联方式,则将明显增大程序体积。另一方面,在现代处理器上,短代码运行效率优于老式处理器,因为现代处理器有更好的指令缓存机制(因此,无须使用内联函数)。</span></span></p>
<p class="a" style="text-indent: 21.1pt; margin: 6pt 0cm;"><span style="font-size: small;"><strong style=""><span style=""><span style="">结论</span>:</span></strong></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">一个比较好的规则就是当函数代码多于</span><span lang="EN-US"><span style="font-family: Times New Roman;">10</span></span><span style="">行时,就不使用内联方式。要特别注意析构函数,它们的实际代码行数很可能大于看到的行数,因为析构函数中可能会隐含成员,还可能会包括父类的析构函数!</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">另一个好的规则是,具有循环体或分支(</span><span lang="EN-US"><span style="font-family: Times New Roman;">switch</span></span><span style="">语句)结构的函数,不宜内联(除非这些循环或分支语句一般不会被执行)。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">即使声明为内联函数,也不一定会被编译为内联函数,这一点很重要。比如虚函数和递归函数一般就不会编译为内联函数。通常,递归函数不应声明为内联函数。将虚函数声明为内联的主要是为了方便或者在文档中说明它的功能(比如取值和赋值函数)。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946442"></a><a name="The_-inl.h_Files"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.4</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><strong><span style="font-size: large;"><span style="">以</span><span lang="EN-US"><span style="font-family: Cambria;">inl.h</span></span></span></strong></span></a><strong><span style="font-size: large;"><span style="">为后缀的文件</span></span></strong></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">复杂内联函数,应当在以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件中进行定义。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">内联函数的定义需要放在头文件内,这样编译器才可以在调用处将其内联展开。但是,实现代码应当放在</span><span style="" lang="EN-US">.cc</span><span style="">文件当中,除非可以提高可读性或运行效率,否则不应该把太多实现代码放在</span><span style="" lang="EN-US">.h</span><span style="">文件中。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">如果内联函数足够短小(只含有极少或是没有逻辑语句),则应该将内联函数放进</span><span style="" lang="EN-US">.h</span><span style="">文件。比如,取值函数和赋值函数就应当放在类的定义里面。为了实现和调用的方便,更复杂的内联函数也应当定义在</span><span style="" lang="EN-US">.h</span><span style="">文件中。如果这样做影响到了代码的可读性,那么可以将这些内联函数放进一个单独的头文件(以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀)。这样可以把内联函数的实现与类定义分开,同时,又不影响在别处包含内联函数实现。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">以</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件的另一个用途是用来定义函数模板。这样做可以提高模板定义的可读性。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">别忘了,与别的头文件一样,</span><span style="" lang="EN-US">-inl.h</span><span style="">为后缀的头文件同样应当</span><span lang="EN-US"><a href="#The__define_Guard"><span style="color: #0000ff;"><span style="" lang="EN-US"><span lang="EN-US">利用</span></span><span style="font-family: Times New Roman;"> #define</span><span style="" lang="EN-US"><span lang="EN-US">防止多重包含</span></span></span></a></span><span style="">。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946443"></a><a name="Function_Parameter_Ordering"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.5</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">函数参数排序</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">定义函数时,参数的顺序应为:输入参数在前,输出参数在后。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C/C++</span></span><span style="">语言中函数的参数分为输入参数与输出参数,也可以既是输入又是输出参数(简称为输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数)。输入参数通常是值类型或者<span style="color: #00b050;">常</span>引用类型,而输出参数与输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数则为非<span style="color: #00b050;">常</span>指针。参数排序时,输入参数应排在其他参数前面。特别地,不能因为参数是新添加的而简单地将参数排到最后,要把新的输入参数排在输出参数前面。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">这条规则并不要求严格遵守。因为输入</span><span lang="EN-US"><span style="font-family: Times New Roman;">/</span></span><span style="">输出参数(通常是类或结构体)很特别,会影响到这条规则。有时为了保持与相关函数的一致性,则不得不违反这条规则。</span></span></p>
<p class="Heading2ForEnglish" style=""><a name="_Toc287946444"></a><a name="Names_and_Order_of_Includes"><span style=""><span style="" lang="EN-US"><span style=""><strong><span style="font-family: Cambria; font-size: large;">1.6</span></strong><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><strong><span style="font-size: large;">文件包含的名称与次数</span></strong></span></span></a></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style=""><span style="font-size: small;">为了可读性并避免隐性依赖(</span></span><span lang="EN-US"><span style="font-family: Times New Roman; font-size: small;">hidden dependencies</span><a style="" name="_ftnref4" href="#_ftn4"><span class="MsoFootnoteReference"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[4]</span></span></span></span></span></a></span><span style="font-size: small;"><span style="">),包含头文件的顺序应当遵循这样的标准:</span><span lang="EN-US"><span style="font-family: Times New Roman;">C</span></span><span style="">库文件,</span><span lang="EN-US"><span style="font-family: Times New Roman;">C++</span></span><span style="">库文件,其他的库文件</span><span style="" lang="EN-US">.h</span><span style="">,本工程中的库文件</span><span style="" lang="EN-US">.h</span><span style="">。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">项目中定义的头文件,都应该放在项目源文件夹中,并且包含语句中不应当含有</span><span lang="EN-US"><span style="font-family: Times New Roman;">UNIX</span></span><span style="">文件夹缩写符号“</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">”(表示当前文件夹),或“</span><span lang="EN-US"><span style="font-family: Times New Roman;">..</span></span><span style="">”(表示上一级文件夹)。例如,</span><span style="" lang="EN-US">google-awesome-project/src/base/logging.h</span><span style="">应当使用这样的包含语句:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/logging.h"</span></p>
</div>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">如果文件</span><em><span style="" lang="EN-US">dir/foo</span></em><span style="" lang="EN-US">.cc</span><span style="">主要用来测试</span><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="">,则应这样排列头文件包含顺序:</span></span></p>
<p class="a" style="text-indent: 24pt; margin: 6pt 0cm;"><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="font-size: small;"><span style="">(优先排序——下面会详细说明原因)</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C</span></span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Times New Roman;">C++</span></span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">其他</span><span style="" lang="EN-US">.h</span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">当前项目</span><span style="" lang="EN-US">.h</span><span style="">库文件</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">优先排序可以减少隐性依赖。每个头文件都应该能独立编译。要达到这样的效果,最简单的方法就是让这些头文件作为</span><span style="" lang="EN-US">.cc</span><span lang="EN-US"><span style="font-family: Times New Roman;">.</span></span><span style="">文件中使用</span><span style="" lang="EN-US">#include</span><span style="">语句包含的第一个</span><span style="" lang="EN-US">.h</span><span style="">文件。</span></span></p>
<p class="a" style="text-indent: 24pt; margin: 6pt 0cm;"><em><span style="" lang="EN-US">dir/foo</span></em><span style="" lang="EN-US">.cc</span><span style="font-size: small;"><span style="">和</span><em><span style="" lang="EN-US">dir2/foo2</span></em><span style="" lang="EN-US">.h</span><span style="">通常在同一文件夹下(比如,</span><span style="" lang="EN-US">base/basictypes_test.cc</span><span style="">和</span><span style="" lang="EN-US">base/basictypes.h</span><span style="">),但也可以在不同的文件夹下。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">每个库的包含语句,最好按字母顺序排序。</span></span></p>
<p class="a" style="text-indent: 21pt; margin: 6pt 0cm;"><span style="font-size: small;"><span style="">例如,</span><span style="" lang="EN-US">google-awesome-project/src/foo/internal/fooserver.cc</span><span style="">中的包含语句可以是这样的:</span></span></p>
<div style="padding-bottom: 3pt; padding-left: 9pt; padding-right: 9pt; background: #f8fff8; padding-top: 3pt;">
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "foo/public/fooserver.h"<span style=""> </span>// Preferred location.</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <sys/types.h></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <unistd.h></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <hash_map></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include <vector></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US"></span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/basictypes.h"</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "base/commandlineflags.h"</span></p>
<p class="MsoNormal" style="text-align: left; margin: 0cm 0cm 0pt; background: #f8fff8; padding: 0cm;" align="left"><span style="" lang="EN-US">#include "foo/public/bar.h"</span></p>
</div>
<div style="">
<br><hr size="1">
<div id="ftn1" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn1" href="#_ftnref1"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[1]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">Linux/Unix</span></span><span style="">下</span><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">源代码文件的扩展名,与</span><span lang="EN-US"><span style="font-family: Calibri;">.cpp</span></span><span style="">等同</span></p>
</div>
<div id="ftn2" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn2" href="#_ftnref2"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[2]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">accessor </span></span><span style="">原意是:函数名以</span><span lang="EN-US"><span style="font-family: Calibri;">get</span></span><span style="">(获取)开头,以要获取的变量名结束,返回值的类型就是要获取变量的类型。故,此处译为取值函数</span></p>
</div>
<div id="ftn3" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn3" href="#_ftnref3"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[3]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:</span><span lang="EN-US"><span style="font-family: Calibri;">mutator</span></span><span style="">原意是:可以修改某个成员变量值的函数,通常指通过一定计算修改某成员变量值的函数(多数情况下就是直接把某个值赋给成员变量)。其实,除了常函数外,所有函数都可以称为</span><span lang="EN-US"><span style="font-family: Calibri;">mutator</span></span><span style="">。故,此处译为赋值函数。</span></p>
</div>
<div id="ftn4" style="">
<p class="MsoFootnoteText" style="margin: 0cm 0cm 0pt;"><a style="" name="_ftn4" href="#_ftnref4"><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><span class="MsoFootnoteReference"><span style="" lang="EN-US"><span style="color: #0000ff;">[4]</span></span></span></span></span></span></a><span lang="EN-US"><span style="font-family: Calibri;"> </span></span><span style="">译者注:隐性依赖是指两个看似相互独立的组件具有的某种关联,这种关联通常由第三方组件中的数据流引起。</span></p>
</div>
</div>
相关推荐
**Google C++ Style Guide** 是一份由Google官方发布的C++编程规范文档,旨在帮助开发人员编写高质量、可维护性强且易于理解的代码。该文档为C++开发者提供了一套详尽的编码规则与建议,涵盖从基础语法到高级特性...
《Thinking in C++ 2nd Edition》是C++编程领域中的经典著作,由Bruce Eckel撰写,分为两卷,分别为Volume One和Volume Two。这两卷书籍深入浅出地介绍了C++编程语言,不仅适合初学者,也对有经验的程序员提供了深入...
【标题】"Felomeng家庭理财2.01Windows7专版"是一个针对Windows7操作系统设计的财务管理软件。这个版本特别优化了与Windows7的兼容性,确保在该系统上运行顺畅,为用户提供高效的家庭财务规划和管理工具。 【描述】...
A_Stochastic_Finite-State_Word-Segmentation_Algorithm_for_Chinese.pdf An_efficient_augmented-context-free_parsing_algorithm.pdf An_Efficient_Context_Free_Parsing_Algorithm.pdf Example-based Machine ...
运行本软件,须.net framework3.5支持。 2.0x版本直接升级不会造成数据损失。... 本软件自2.0版开始,数据格式与1.xx版本不再兼容,采用了全新的数据管理方式,并且对于字段也略有调整。对此给您造成的不便敬请谅解。
Felomeng家庭理财2.23,简单易用的理财软件
"Felomeng家庭理财"是一款专为个人和家庭设计的财务管理软件,旨在帮助用户更好地管理他们的财务状况。这款软件提供了全面的预算规划、收支记录、投资跟踪和报表分析等功能,让用户能够清晰地了解自己的财务状况,...
1.xx版设计比较失败,2.xx版本采取了完全不同的架构与理念(虽然界面,使用方法上基本保持了一致)。故1.xx代码不再具有保密的必要,拿出来与大家分享。 这是我来北大软院学习前编写的软件,谈不上设计,学习价值...
本工具可以计算: 工资、薪金所得 个体工商户生产、经营所得 企事业单位的承包经营、承 租经营所得 劳务报酬所得 稿酬所得 特许权使用所得 利息、股息、红利所得 财产租赁所得 财产转让所得 ...
VB(Visual Basic)是一种由微软开发的编程环境,主要用于创建Windows桌面应用程序。在这个"VB图片查看程序"中,我们关注的是如何使用VB来实现图片的加载和显示功能。这个程序作为一个学习示例,旨在帮助初学者理解...
1. **C#编程语言**:C#是一种面向对象的编程语言,由微软开发,用于构建Windows平台的应用程序。在本项目中,C#被用来实现文本相似度检测的算法和系统框架,具有高效、易于理解和强大的库支持。 2. **VSM空间向量...
《VC6学习指南配套代码》是针对Microsoft Visual C++ 6.0(简称VC6)这一经典编程环境的学习资源,通常与《learn microsoft visual c++6.0 now》这本书的实践部分相配合。这本书旨在帮助读者快速掌握C++编程语言以及...
【标题】"wxWidgets2.8.10和CodeBlocks8.02"涉及的是两个重要的开源工具,它们是开发跨平台C++应用程序的关键组件。wxWidgets是一个C++库,而CodeBlocks则是一个集成开发环境(IDE)。 【wxWidgets 2.8.10】是...
在`Felomeng.MoreEffectiveVSMSimilarity.sln`和`Felomeng.VSMSimilarity`这两个文件中,很可能包含了项目解决方案和主要的相似度计算类。通过打开并分析这些文件,我们可以看到具体的实现代码,包括如何构建词汇表...
【VB计算器】是一种基于Visual Basic(VB)编程语言开发的简单计算器应用,它通常用于教学目的,帮助初学者理解可视化编程的基本概念。VB是一种面向对象的编程语言,由微软公司开发,广泛应用于Windows应用程序的...
例如,Felomeng.PersonalTaxCalculatorSetup可能就是一款个人所得税计算器的安装程序,用户下载安装后,可以输入工资、社保、公积金等数据,软件会自动计算出应缴税款,节省时间和精力。 使用个人所得税计算器时,...
在C#编程环境中,我们可以构建HMM来实现中文分词,这是一种将文本字符串分割成有意义的词语的过程。 **HMM基本概念** 1. **状态(State)**: 在HMM中,状态是不可见的,代表了模型内部的一种动态过程。 2. **观测...
1. **IKVM.Runtime.dll**:这是IKVM的核心组件,它实现了Java虚拟机(JVM)的大部分功能,包括字节码解释器、垃圾收集器和类加载器等。它使得.NET平台能够理解和执行Java字节码。 2. **IKVM.OpenJDK.ClassLibrary....
7. **API接口**:提供C、C++、Java、Python等编程语言的接口使用示例,帮助开发者将LibSVM集成到自己的项目中。 8. **性能优化**:可能包括关于并行计算、内存管理等方面的建议,以提高模型训练和预测的效率。 9. ...