mirror of
https://github.com/zh-google-styleguide/zh-google-styleguide.git
synced 2025-02-19 20:50:10 +08:00
headers.rst: 翻译新章节「1.3. 前向声明」
此外不再翻译 symbol 为语焉不详的「符号」,直接上原单词
This commit is contained in:
parent
2d7e95afc1
commit
85f1e3aa34
@ -11,7 +11,7 @@
|
||||
|
||||
头文件应该能够自给自足(self-contained),以 ``in.h`` 结尾。至于用来插入文本的文件,说到底它们并不是头文件,所以应以 ``.inc`` 结尾。
|
||||
|
||||
所有头文件要能够自给自足。换言之,用户和重构工具不需要为特别场合而包含额外的头文件。详言之,一个头文件要有 #define 保护,统统包含它所需要的其它头文件,也不要求定义任何特别符号(symbols)。
|
||||
所有头文件要能够自给自足。换言之,用户和重构工具不需要为特别场合而包含额外的头文件。详言之,一个头文件要有 #define 保护,统统包含它所需要的其它头文件,也不要求定义任何特别 symbols.
|
||||
|
||||
不过有一个例外,即一个文件并不是 self-contained 的,而是用来安插到代码某处里,特别是要安插多次的时候。或者,文件内容实际上是其它头文件的特定平台(platform-specific)扩展部分。这些文件就要用 ``.inc`` 文件扩展名。
|
||||
|
||||
@ -36,7 +36,41 @@ As an exception, a function template that is explicitly instantiated for all rel
|
||||
#define FOO_BAR_BAZ_H_
|
||||
…
|
||||
#endif // FOO_BAR_BAZ_H_
|
||||
|
||||
.. _forward_declarations:
|
||||
|
||||
1.3. 前向声明
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
您可以靠前置声明来避免多余的 ``#includes``.
|
||||
|
||||
定义:
|
||||
|
||||
所谓「前向声明」(forward declaration)是类,函数和模板的纯粹声明,没伴随着其定义。代码中用到了哪些 symbols, 往往可以用其前向声明来代替对应的 ``#inclues``.
|
||||
|
||||
优点:
|
||||
|
||||
* 多余的 ``#includes`` 会害得编译器花费不少时间展开更多文件,处理大量输入。
|
||||
* 而且一旦改动头文件,就得重新编译整个文件。
|
||||
|
||||
缺点:
|
||||
|
||||
* 如果前向声明关系到模板,typedefs, 默认参数和 using 声明,就很难决定它的具体样子了。
|
||||
* 很难判断什么时候该用前向声明,什么时候该用 ``#includes``, 特别是涉及隐式转换运算符的时候。极端情况下,用前向声明代替 ``includes`` 甚至都会暗暗地改变代码的含义。
|
||||
* 前向声明了不少来自头文件的 symbol 时,就会比单单 ``includes`` 一行冗长。
|
||||
* 前向声明函数或模板有时会害得头文件开发者难以轻易变动其 API. 就像扩大形参类型,加个自带默认参数的模板形参等等。
|
||||
* 前向声明来自命名空间 ``std::` 的 symbol 时,其行为为定义。
|
||||
* 仅仅为了能前向声明而重构代码(比如用指针成员代替对象成员),后者会变慢且复杂起来。
|
||||
* 还没有实践证实前向声明的优越性。
|
||||
|
||||
决定:
|
||||
|
||||
* 函数:用 ``#include``.
|
||||
* 类模板:优先用 ``#includes``.
|
||||
* 类:用前向声明固然不错,但小心点。若说不定,还是用 ``#includes`` 好了。
|
||||
* 千万别为了避免 ``includes`` 而把数据成员改成指针。
|
||||
|
||||
至于什么时候包含头文件,参见 :ref:```#include`` 的路径及顺序`。
|
||||
|
||||
.. _inline-functions:
|
||||
|
||||
@ -99,7 +133,7 @@ C/C++ 函数参数分为输入参数, 输出参数, 和输入/输出参数三种
|
||||
|
||||
按字母顺序对头文件包含进行二次排序是不错的主意 (yospaly 译注: 之前已经按头文件类别排过序了).
|
||||
|
||||
您所依赖(rely upon)的符号(symbols)被哪些头文件所定义,您就应该包含(include)哪些头文件,forward declaration 情况除外。比如您要用到 ``bar.h`` 中的某个符号,哪怕您所包含的 ``foo.h`` 已经包含了 ``bar.h``, 也照样得包含 ``bar.h``, 除非 ``foo.h`` 有明确说明它会自动向您提供 ``bar.h`` 中的符号。不过,凡是 cc 文件所对应的「相关头文件」已经包含的,就不用再重复包含进其 cc 文件里面了,就像 ``foo.cc`` 只包含 ``foo.h`` 就够了,不用再管后者所包含的其它内容。
|
||||
您所依赖的 symbols 被哪些头文件所定义,您就应该包含(include)哪些头文件,forward declaration 情况除外。比如您要用到 ``bar.h`` 中的某个 symbol, 哪怕您所包含的 ``foo.h`` 已经包含了 ``bar.h``, 也照样得包含 ``bar.h``, 除非 ``foo.h`` 有明确说明它会自动向您提供 ``bar.h`` 中的 symbol. 不过,凡是 cc 文件所对应的「相关头文件」已经包含的,就不用再重复包含进其 cc 文件里面了,就像 ``foo.cc`` 只包含 ``foo.h`` 就够了,不用再管后者所包含的其它内容。
|
||||
|
||||
举例来说, ``google-awesome-project/src/foo/internal/fooserver.cc`` 的包含次序如下:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user