From d485dddef0532809f954b3abe87116f0b872b5ee Mon Sep 17 00:00:00 2001 From: "Ling.Li" Date: Tue, 18 Apr 2017 23:49:41 +0800 Subject: [PATCH 1/8] Ling.Li: Update .gitignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6fafe70..f1ea110 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# JetBrains Webstorm Config Files +.idea/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] From 8f9f6fe22deec4c9fc1b5109a72a74f66279de63 Mon Sep 17 00:00:00 2001 From: "Ling.Li" Date: Wed, 19 Apr 2017 00:01:02 +0800 Subject: [PATCH 2/8] Ling.Li: Finish modify Chapter 11. --- google-cpp-styleguide/end.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/google-cpp-styleguide/end.rst b/google-cpp-styleguide/end.rst index 101e2eb..83247ad 100644 --- a/google-cpp-styleguide/end.rst +++ b/google-cpp-styleguide/end.rst @@ -1,12 +1,10 @@ -10. 结束语 +11. 结束语 ~~~~~~~~~~~~~~~~ -.. tip:: - - 运用常识和判断力, 并 *保持一致*. +运用常识和判断力, 并且 *保持一致*. 编辑代码时, 花点时间看看项目中的其它代码, 并熟悉其风格. 如果其它代码中 ``if`` 语句使用空格, 那么你也要使用. 如果其中的注释用星号 (*) 围成一个盒子状, 你同样要这么做. -风格指南的重点在于提供一个通用的编程规范, 这样大家可以把精力集中在实现内容而不是表现形式上. 我们展示了全局的风格规范, 但局部风格也很重要, 如果你在一个文件中新加的代码和原有代码风格相去甚远, 这就破坏了文件本身的整体美观, 也影响阅读, 所以要尽量避免. +风格指南的重点在于提供一个通用的编程规范, 这样大家可以把精力集中在实现内容而不是表现形式上. 我们展示的是一个总体的的风格规范, 但局部风格也很重要, 如果你在一个文件中新加的代码和原有代码风格相去甚远, 这就破坏了文件本身的整体美观, 也让打乱读者在阅读代码时的节奏, 所以要尽量避免. 好了, 关于编码风格写的够多了; 代码本身才更有趣. 尽情享受吧! From fd8ef076660d034e977e36a10139d95263026334 Mon Sep 17 00:00:00 2001 From: "Ling.Li" Date: Wed, 19 Apr 2017 00:03:26 +0800 Subject: [PATCH 3/8] Ling.Li: Please note that Google C++ Style Guide has added a new chapter 'Functions' as Chapter 4. So the current Chapter 11 is the previous Chapter 10. --- google-cpp-styleguide/end.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cpp-styleguide/end.rst b/google-cpp-styleguide/end.rst index 83247ad..7dcd4f4 100644 --- a/google-cpp-styleguide/end.rst +++ b/google-cpp-styleguide/end.rst @@ -3,7 +3,7 @@ 运用常识和判断力, 并且 *保持一致*. -编辑代码时, 花点时间看看项目中的其它代码, 并熟悉其风格. 如果其它代码中 ``if`` 语句使用空格, 那么你也要使用. 如果其中的注释用星号 (*) 围成一个盒子状, 你同样要这么做. +编辑代码时, 花点时间看看项目中的其它代码, 并熟悉其风格. 如果其它代码中 ``if`` 语句使用空格, 那么你也要使用. 如果其中的注释用星号 (*) 围成一个盒子状, 那么你同样要这么做. 风格指南的重点在于提供一个通用的编程规范, 这样大家可以把精力集中在实现内容而不是表现形式上. 我们展示的是一个总体的的风格规范, 但局部风格也很重要, 如果你在一个文件中新加的代码和原有代码风格相去甚远, 这就破坏了文件本身的整体美观, 也让打乱读者在阅读代码时的节奏, 所以要尽量避免. From 46a0f13d5153b1777e8a491eb04173a8712111ef Mon Sep 17 00:00:00 2001 From: "Ling.Li" Date: Wed, 19 Apr 2017 00:34:16 +0800 Subject: [PATCH 4/8] Ling.Li: Finish modify Chapter 10. --- google-cpp-styleguide/README.md | 7 ++++++ google-cpp-styleguide/exceptions.rst | 32 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 google-cpp-styleguide/README.md diff --git a/google-cpp-styleguide/README.md b/google-cpp-styleguide/README.md new file mode 100644 index 0000000..f194eaa --- /dev/null +++ b/google-cpp-styleguide/README.md @@ -0,0 +1,7 @@ +# lilinsanity 的改动说明 + +我对 Google C++ Style Guide 又做了一次修改, 主要修改了这些地方: + +1. 调整了章节, 增加了新的 **函数** 一节. +2. 统一标点符号为英文标点符号. +3. 调整了排版, 在每个小节底下用加粗字体分段为"总述""优点""缺点""结论"等. 其中"总述"为原来的 TIPS, 我认为这样的排版显得有些混乱, 不够美观, 因此改成了和"优点""缺点"等并列的一段. diff --git a/google-cpp-styleguide/exceptions.rst b/google-cpp-styleguide/exceptions.rst index f67683e..5effa73 100644 --- a/google-cpp-styleguide/exceptions.rst +++ b/google-cpp-styleguide/exceptions.rst @@ -1,4 +1,4 @@ -9. 规则特例 +10. 规则特例 ------------------ 前面说明的编程习惯基本都是强制性的. 但所有优秀的规则都允许例外, 这里就是探讨这些特例. @@ -6,40 +6,44 @@ 9.1. 现有不合规范的代码 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 对于现有不符合既定编程风格的代码可以网开一面. +对于现有不符合既定编程风格的代码可以网开一面. -当你修改使用其他风格的代码时, 为了与代码原有风格保持一致可以不使用本指南约定. 如果不放心可以与代码原作者或现在的负责人员商讨, 记住, *一致性* 包括原有的一致性. +**说明** + +当你修改使用其他风格的代码时, 为了与代码原有风格保持一致可以不使用本指南约定. 如果不放心, 可以与代码原作者或现在的负责人员商讨. 记住, *一致性* 也包括原有的一致性. .. _windows-code: 9.2. Windows 代码 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - Windows 程序员有自己的编程习惯, 主要源于 Windows 头文件和其它 Microsoft 代码. 我们希望任何人都可以顺利读懂你的代码, 所以针对所有平台的 C++ 编程只给出一个单独的指南. +Windows 程序员有自己的编程习惯, 主要源于 Windows 头文件和其它 Microsoft 代码. 我们希望任何人都可以顺利读懂你的代码, 所以针对所有平台的 C++ 编程只给出一个单独的指南. + +**说明** 如果你习惯使用 Windows 编码风格, 这儿有必要重申一下某些你可能会忘记的指南: - 不要使用匈牙利命名法 (比如把整型变量命名成 ``iNum``). 使用 Google 命名约定, 包括对源文件使用 ``.cc`` 扩展名. - - Windows 定义了很多原生类型的同义词 (YuleFox 注: 这一点, 我也很反感), 如 ``DWORD``, ``HANDLE`` 等等. 在调用 Windows API 时这是完全可以接受甚至鼓励的. 但还是尽量使用原有的 C++ 类型, 例如, 使用 ``const TCHAR *`` 而不是 ``LPCTSTR``. + - Windows 定义了很多原生类型的同义词 (YuleFox 注: 这一点, 我也很反感), 如 ``DWORD``, ``HANDLE`` 等等. 在调用 Windows API 时这是完全可以接受甚至鼓励的. 即使如此, 还是尽量使用原有的 C++ 类型, 例如使用 ``const TCHAR *`` 而不是 ``LPCTSTR``. - - 使用 Microsoft Visual C++ 进行编译时, 将警告级别设置为 3 或更高, 并将所有 warnings 当作 errors 处理. + - 使用 Microsoft Visual C++ 进行编译时, 将警告级别设置为 3 或更高, 并将所有警告(warnings)当作错误(errors)处理. - - 不要使用 ``#pragma once``; 而应该使用 Google 的头文件保护规则. 头文件保护的路径应该相对于项目根目录 (Yang.Y 注: 如 ``#ifndef SRC_DIR_BAR_H_``, 参考 :ref:`#define 保护 ` 一节). + - 不要使用 ``#pragma once``; 而应该使用 Google 的头文件保护规则. 头文件保护的路径应该相对于项目根目录 (Yang.Y 注: 如 ``#ifndef SRC_DIR_BAR_H_``, 参考 :ref:`#define 保护 ` 一节). - - 除非万不得已, 不要使用任何非标准的扩展, 如 ``#pragma`` 和 ``__declspec``. 允许使用 ``__declspec(dllimport)`` 和 ``__declspec(dllexport)``; 但你必须通过宏来使用, 比如 ``DLLIMPORT`` 和 ``DLLEXPORT``, 这样其他人在分享使用这些代码时很容易就去掉这些扩展. + - 除非万不得已, 不要使用任何非标准的扩展, 如 ``#pragma`` 和 ``__declspec``. 使用 ``__declspec(dllimport)`` 和 ``__declspec(dllexport)`` 是允许的, 但必须通过宏来使用, 比如 ``DLLIMPORT`` 和 ``DLLEXPORT``, 这样其他人在分享使用这些代码时可以很容易地禁用这些扩展. -在 Windows 上, 只有很少的一些情况下, 我们可以偶尔违反规则: +然而, 在 Windows 上仍然有一些我们偶尔需要违反的规则: - 通常我们 :ref:`禁止使用多重继承 `, 但在使用 COM 和 ATL/WTL 类时可以使用多重继承. 为了实现 COM 或 ATL/WTL 类/接口, 你可能不得不使用多重实现继承. - - 虽然代码中不应该使用异常, 但是在 ATL 和部分 STL(包括 Visual C++ 的 STL) 中异常被广泛使用. 使用 ATL 时, 应定义 ``_ATL_NO_EXCEPTIONS`` 以禁用异常. 你要研究一下是否能够禁用 STL 的异常, 如果无法禁用, 启用编译器异常也可以. (注意这只是为了编译 STL, 自己代码里仍然不要含异常处理.) + - 虽然代码中不应该使用异常, 但是在 ATL 和部分 STL(包括 Visual C++ 的 STL) 中异常被广泛使用. 使用 ATL 时, 应定义 ``_ATL_NO_EXCEPTIONS`` 以禁用异常. 你需要研究一下是否能够禁用 STL 的异常, 如果无法禁用, 可以启用编译器异常. (注意这只是为了编译 STL, 自己的代码里仍然不应当包含异常处理). - - 通常为了利用头文件预编译, 每个每个源文件的开头都会包含一个名为 ``StdAfx.h`` 或 ``precompile.h`` 的文件. 为了使代码方便与其他项目共享, 避免显式包含此文件 (``precompile.cc``), 使用 ``/FI`` 编译器选项以自动包含. + - 通常为了利用头文件预编译, 每个每个源文件的开头都会包含一个名为 ``StdAfx.h`` 或 ``precompile.h`` 的文件. 为了使代码方便与其他项目共享, 请避免显式包含此文件 (除了在 ``precompile.cc`` 中), 使用 ``/FI`` 编译器选项以自动包含该文件. - - 资源头文件通常命名为 ``resource.h``, 且只包含宏的, 不需要遵守本风格指南. + - 资源头文件通常命名为 ``resource.h`` 且只包含宏, 这一文件不需要遵守本风格指南. From 39d12a755c68cd87240fac9455cd8468971be1ef Mon Sep 17 00:00:00 2001 From: "Ling.Li" Date: Wed, 19 Apr 2017 00:35:42 +0800 Subject: [PATCH 5/8] Ling.Li: Correct the chapter no. --- google-cpp-styleguide/exceptions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cpp-styleguide/exceptions.rst b/google-cpp-styleguide/exceptions.rst index 5effa73..bb0df0c 100644 --- a/google-cpp-styleguide/exceptions.rst +++ b/google-cpp-styleguide/exceptions.rst @@ -3,7 +3,7 @@ 前面说明的编程习惯基本都是强制性的. 但所有优秀的规则都允许例外, 这里就是探讨这些特例. -9.1. 现有不合规范的代码 +10.1. 现有不合规范的代码 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **总述** @@ -16,7 +16,7 @@ .. _windows-code: -9.2. Windows 代码 +10.2. Windows 代码 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **总述** From fee366c598c6cbf5e69d1ca394af0f8062f2b076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=87=8C?= Date: Wed, 19 Apr 2017 01:30:07 +0800 Subject: [PATCH 6/8] Ling.Li: Partly modify Chapter 9. It's so late and I need to go to bed. --- google-cpp-styleguide/formatting.rst | 465 ++++++++++++++------------- 1 file changed, 246 insertions(+), 219 deletions(-) diff --git a/google-cpp-styleguide/formatting.rst b/google-cpp-styleguide/formatting.rst index 447bfc9..7cb0d59 100644 --- a/google-cpp-styleguide/formatting.rst +++ b/google-cpp-styleguide/formatting.rst @@ -1,259 +1,286 @@ -8. 格式 +9. 格式 ------------ -代码风格和格式确实比较随意, 但一个项目中所有人遵循同一风格是非常容易的. 个体未必同意下述每一处格式规则, 但整个项目服从统一的编程风格是很重要的, 只有这样才能让所有人能很轻松的阅读和理解代码. +每个人都可能有自己的代码风格和格式, 但如果一个项目中的所有人都遵循同一风格的话, 这个项目就能更顺利地进行. 每个人未必能同意下述的每一处格式规则, 而且其中的不少规则需要一定时间的适应, 但整个项目服从统一的编程风格是很重要的, 只有这样才能让所有人轻松地阅读和理解代码. -另外, 我们写了一个 `emacs 配置文件 `_ 来帮助你正确的格式化代码. +为了帮助你正确的格式化代码, 我们写了一个 `emacs 配置文件 `_. .. _line-length: -8.1. 行长度 +9.1. 行长度 ~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 每一行代码字符数不超过 80. +每一行代码字符数不超过 80. -我们也认识到这条规则是有争议的, 但很多已有代码都已经遵照这一规则, 我们感觉一致性更重要. +我们也认识到这条规则是有争议的, 但很多已有代码都遵照这一规则, 因此我们感觉一致性更重要. -优点: +**优点** - 提倡该原则的人主张强迫他们调整编辑器窗口大小很野蛮. 很多人同时并排开几个代码窗口, 根本没有多余空间拉伸窗口. 大家都把窗口最大尺寸加以限定, 并且 80 列宽是传统标准. 为什么要改变呢? +提倡该原则的人认为强迫他们调整编辑器窗口大小是很野蛮的行为. 很多人同时并排开几个代码窗口, 根本没有多余的空间拉伸窗口. 大家都把窗口最大尺寸加以限定, 并且 80 列宽是传统标准. 那么为什么要改变呢? -缺点: +**缺点** - 反对该原则的人则认为更宽的代码行更易阅读. 80 列的限制是上个世纪 60 年代的大型机的古板缺陷; 现代设备具有更宽的显示屏, 很轻松的可以显示更多代码. +反对该原则的人则认为更宽的代码行更易阅读. 80 列的限制是上个世纪 60 年代的大型机的古板缺陷; 现代设备具有更宽的显示屏, 可以很轻松地显示更多代码. -结论: +**结论** - 80 个字符是最大值. +80 个字符是最大值. - 特例: +如果无法在不伤害易读性的条件下进行断行, 那么注释行可以超过 80 个字符, 这样可以方便复制粘贴. 例如, 带有命令示例或 URL 的行可以超过 80 个字符. - - 如果一行注释包含了超过 80 字符的命令或 URL, 出于复制粘贴的方便允许该行超过 80 字符. - - 包含长路径的 ``#include`` 语句可以超出80列. 但应该尽量避免. - - :ref:`头文件保护 ` 可以无视该原则. +包含长路径的 ``#include`` 语句可以超出80列. -8.2. 非 ASCII 字符 +:ref:`头文件保护 ` 可以无视该原则. + +9.2. 非 ASCII 字符 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 尽量不使用非 ASCII 字符, 使用时必须使用 UTF-8 编码. +尽量不使用非 ASCII 字符, 使用时必须使用 UTF-8 编码. -即使是英文, 也不应将用户界面的文本硬编码到源代码中, 因此非 ASCII 字符要少用. 特殊情况下可以适当包含此类字符. 如, 代码分析外部数据文件时, 可以适当硬编码数据文件中作为分隔符的非 ASCII 字符串; 更常见的是 (不需要本地化的) 单元测试代码可能包含非 ASCII 字符串. 此类情况下, 应使用 UTF-8 编码, 因为很多工具都可以理解和处理 UTF-8 编码. +**说明** -十六进制编码也可以, 能增强可读性的情况下尤其鼓励 —— 比如 ``"\xEF\xBB\xBF"`` 在 Unicode 中是 *零宽度 无间断* 的间隔符号, 如果不用十六进制直接放在 UTF-8 格式的源文件中, 是看不到的. +即使是英文, 也不应将用户界面的文本硬编码到源代码中, 因此非 ASCII 字符应当很少被用到. 特殊情况下可以适当包含此类字符. 例如, 代码分析外部数据文件时, 可以适当硬编码数据文件中作为分隔符的非 ASCII 字符串; 更常见的是 (不需要本地化的) 单元测试代码可能包含非 ASCII 字符串. 此类情况下, 应使用 UTF-8 编码, 因为很多工具都可以理解和处理 UTF-8 编码. + +十六进制编码也可以, 能增强可读性的情况下尤其鼓励 —— 比如 ``"\xEF\xBB\xBF"`, 或者更简洁地写作 ``u8"\uFEFF"``, 在 Unicode 中是 *零宽度 无间断* 的间隔符号, 如果不用十六进制直接放在 UTF-8 格式的源文件中, 是看不到的. (Yang.Y 注: ``"\xEF\xBB\xBF"`` 通常用作 UTF-8 with BOM 编码标记) -用 ``u8`` 前缀以把带 ``uXXXX`` 转义序列的字符串字面值编码成 UTF-8. 不要用在本身就带 UTF-8 字符的字符串字面值上,因为如果编译器不把源代码识别成 UTF-8, 输出就会出错。 +使用 ``u8`` 前缀把带 ``uXXXX`` 转义序列的字符串字面值编码成 UTF-8. 不要用在本身就带 UTF-8 字符的字符串字面值上, 因为如果编译器不把源代码识别成 UTF-8, 输出就会出错. -别用 C++11 的 ``char16_t`` 和 ``char32_t``, 它们和 UTF-8 文本没有关系,``wchar_t`` 同理,除非您写的代码要调用 Windows API, 后者有用到 ``wchar_t`` 扩展。 +别用 C++11 的 ``char16_t`` 和 ``char32_t``, 它们和 UTF-8 文本没有关系, ``wchar_t`` 同理, 除非你写的代码要调用 Windows API, 后者广泛使用了 ``wchar_t``. -8.3. 空格还是制表位 +9.3. 空格还是制表位 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 只使用空格, 每次缩进 2 个空格. +只使用空格, 每次缩进 2 个空格. -我们使用空格缩进. 不要在代码中使用制符表. 你应该设置编辑器将制符表转为空格. +**说明** -8.4. 函数声明与定义 +我们使用空格缩进. 不要在代码中使用制表符. 你应该设置编辑器将制表符转为空格. + +9.4. 函数声明与定义 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 返回类型和函数名在同一行, 参数也尽量放在同一行,如果放不下就对形参分行。 +返回类型和函数名在同一行, 参数也尽量放在同一行, 如果放不下就对形参分行, 分行方式与 :ref:`函数调用 ` 一致. + +**说明** 函数看上去像这样: - .. code-block:: c++ +.. code-block:: c++ - ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) { - DoSomething(); - ... - } + ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) { + DoSomething(); + ... + } 如果同一行文本太多, 放不下所有参数: - .. code-block:: c++ +.. code-block:: c++ - ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2, - Type par_name3) { - DoSomething(); - ... - } + ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2, + Type par_name3) { + DoSomething(); + ... + } 甚至连第一个参数都放不下: - .. code-block:: c++ +.. code-block:: c++ - ReturnType LongClassName::ReallyReallyReallyLongFunctionName( - Type par_name1, // 4 空格缩进 - Type par_name2, - Type par_name3) { - DoSomething(); // 2 空格缩进 - ... - } + ReturnType LongClassName::ReallyReallyReallyLongFunctionName( + Type par_name1, // 4 space indent + Type par_name2, + Type par_name3) { + DoSomething(); // 2 space indent + ... + } 注意以下几点: - - 如果返回类型和函数名在一行放不下,分行。 +- 使用好的参数名. - - 如果返回类型那个与函数声明或定义分行了,不要缩进。 +- 只有在参数未被使用或者其用途非常明显时, 才能省略参数名. - - 左圆括号总是和函数名在同一行; +- 如果返回类型和函数名在一行放不下, 分行. - - 函数名和左圆括号间没有空格; +- 如果返回类型与函数声明或定义分行了, 不要缩进. - - 圆括号与参数间没有空格; +- 左圆括号总是和函数名在同一行. - - 左大括号总在最后一个参数同一行的末尾处; +- 函数名和左圆括号间永远没有空格. - - 如果其它风格规则允许的话,右大括号总是单独位于函数最后一行,或者与左大括号同一行。 +- 圆括号与参数间没有空格. - - 右大括号和左大括号间总是有一个空格; +- 左大括号总在最后一个参数同一行的末尾处, 不另起新行. - - 函数声明和定义中的所有形参必须有命名且一致; +- 右大括号总是单独位于函数最后一行, 或者与左大括号同一行. - - 所有形参应尽可能对齐; +- 右圆括号和左大括号间总是有一个空格. - - 缺省缩进为 2 个空格; +- 所有形参应尽可能对齐. - - 换行后的参数保持 4 个空格的缩进; +- 缺省缩进为 2 个空格. -如果有些参数没有用到, 在函数定义处将参数名注释起来: +- 换行后的参数保持 4 个空格的缩进. - .. code-block:: c++ +未被使用的参数, 或者根据上下文很容易看出其用途的参数, 可以省略参数名: - // 接口中形参恒有命名。 - class Shape { - public: - virtual void Rotate(double radians) = 0; - } +.. code-block:: c++ - // 声明中形参恒有命名。 - class Circle : public Shape { - public: - virtual void Rotate(double radians); - } + class Foo { + public: + Foo(Foo&&); + Foo(const Foo&); + Foo& operator=(Foo&&); + Foo& operator=(const Foo&); + }; - // 定义中注释掉无用变量。 - void Circle::Rotate(double /*radians*/) {} +未被使用的参数如果其用途不明显的话, 在函数定义处将参数名注释起来: - .. warning:: +.. code-block:: c++ - .. code-block:: c++ + class Shape { + public: + virtual void Rotate(double radians) = 0; + }; - // 差 - 如果将来有人要实现,很难猜出变量是干什么用的。 - void Circle::Rotate(double) {} + class Circle : public Shape { + public: + void Rotate(double radians) override; + }; -8.5. Lambda 表达式 + void Circle::Rotate(double /*radians*/) {} + +.. code-block:: c++ + + // 差 - 如果将来有人要实现, 很难猜出变量的作用. + void Circle::Rotate(double) {} + +属性, 和展开为属性的宏, 写在函数声明或定义的最前面, 即返回类型之前: + +.. code-block:: c++ + + MUST_USE_RESULT bool IsOK(); + +9.5. Lambda 表达式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 其它函数怎么格式化形参和函数体,Lambda 表达式就怎么格式化;捕获列表同理。 +Lambda 表达式对形参和函数体的格式化和其他函数一致; 捕获列表同理, 表项用逗号隔开. - 若用引用捕获,在变量名和 ``&`` 之间不留空格。 +**说明** - .. code-block:: c++ +若用引用捕获, 在变量名和 ``&`` 之间不留空格. - int x = 0; - auto add_to_x = [&x](int n) { x += n; }; +.. code-block:: c++ - 短 lambda 就写得和内联函数一样。 + int x = 0; + auto add_to_x = [&x](int n) { x += n; }; - .. code-block:: c++ +短 lambda 就写得和内联函数一样. - std::set blacklist = {7, 8, 9}; - std::vector digits = {3, 9, 1, 8, 4, 7, 1}; - digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) { - return blacklist.find(i) != blacklist.end(); - }), - digits.end()); +.. code-block:: c++ -8.6. 函数调用 + std::set blacklist = {7, 8, 9}; + std::vector digits = {3, 9, 1, 8, 4, 7, 1}; + digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) { + return blacklist.find(i) != blacklist.end(); + }), + digits.end()); + +.. _function-calls: + +9.6. 函数调用 ~~~~~~~~~~~~~~~~~~~~~~ -.. tip:: +**总述** - 要么一行写完函数调用,要么在圆括号里对参数分行,要么参数另起一行且缩进四格。如果没有其它顾虑的话,尽可能精简行数,比如把多个参数适当地放在同一行里。 +要么一行写完函数调用, 要么在圆括号里对参数分行, 要么参数另起一行且缩进四格. 如果没有其它顾虑的话, 尽可能精简行数, 比如把多个参数适当地放在同一行里. - 函数调用遵循如下形式: +**说明** - .. code-block:: c++ +函数调用遵循如下形式: - bool retval = DoSomething(argument1, argument2, argument3); +.. code-block:: c++ - 如果同一行放不下,可断为多行,后面每一行都和第一个实参对齐,左圆括号后和右圆括号前不要留空格: + bool retval = DoSomething(argument1, argument2, argument3); - .. code-block:: c++ +如果同一行放不下, 可断为多行, 后面每一行都和第一个实参对齐, 左圆括号后和右圆括号前不要留空格: - bool retval = DoSomething(averyveryveryverylongargument1, - argument2, argument3); +.. code-block:: c++ - 参数也可以放在次行,缩进四格: + bool retval = DoSomething(averyveryveryverylongargument1, + argument2, argument3); - .. code-block:: c++ +参数也可以放在次行, 缩进四格: - if (...) { - ... - ... - if (...) { - DoSomething( - argument1, argument2, // 4 空格缩进 - argument3, argument4); - } +.. code-block:: c++ - 把多个参数放在同一行,是为了减少函数调用所需的行数,除非影响到可读性。有人认为把每个参数都独立成行,不仅更好读,而且方便编辑参数。不过,比起所谓的参数编辑,我们更看重可读性,且后者比较好办: + if (...) { + ... + ... + if (...) { + DoSomething( + argument1, argument2, // 4 空格缩进 + argument3, argument4); + } - 如果一些参数本身就是略复杂的表达式,且降低了可读性。那么可以直接创建临时变量描述该表达式,并传递给函数: +把多个参数放在同一行以减少函数调用所需的行数, 除非影响到可读性. 有人认为把每个参数都独立成行, 不仅更好读, 而且方便编辑参数. 不过, 比起所谓的参数编辑, 我们更看重可读性, 且后者比较好办: - .. code-block:: c++ +如果一些参数本身就是略复杂的表达式, 且降低了可读性, 那么可以直接创建临时变量描述该表达式, 并传递给函数: - int my_heuristic = scores[x] * y + bases[x]; - bool retval = DoSomething(my_heuristic, x, y, z); +.. code-block:: c++ - 或者放着不管,补充上注释: + int my_heuristic = scores[x] * y + bases[x]; + bool retval = DoSomething(my_heuristic, x, y, z); - .. code-block:: c++ +或者放着不管, 补充上注释: - bool retval = DoSomething(scores[x] * y + bases[x], // Score heuristic. - x, y, z); +.. code-block:: c++ - 如果某参数独立成行,对可读性更有帮助的话,就这么办。 + bool retval = DoSomething(scores[x] * y + bases[x], // Score heuristic. + x, y, z); - 此外,如果一系列参数本身就有一定的结构,可以酌情地按其结构来决定参数格式: +如果某参数独立成行, 对可读性更有帮助的话, 那也可以如此做. 参数的格式处理应当以可读性而非其他作为最重要的原则. - .. code-block:: c++ +此外, 如果一系列参数本身就有一定的结构, 可以酌情地按其结构来决定参数格式: - // 通过 3x3 矩阵转换 widget. - my_widget.Transform(x1, x2, x3, - y1, y2, y3, - z1, z2, z3); +.. code-block:: c++ + + // 通过 3x3 矩阵转换 widget. + my_widget.Transform(x1, x2, x3, + y1, y2, y3, + z1, z2, z3); .. _braced-initializer-list-format -8.7. 列表初始化格式 +9.7. 列表初始化格式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: - 您平时怎么格式化函数调用,就怎么格式化 :ref:`braced_initializer_list`。 + 您平时怎么格式化函数调用, 就怎么格式化 :ref:`braced_initializer_list`. - 如果列表初始化伴随着名字,比如类型或变量名,您可以当名字是函数、{} 是函数调用的括号来格式化它。反之,就当它有个长度为零的名字。 + 如果列表初始化伴随着名字, 比如类型或变量名, 您可以当名字是函数、{} 是函数调用的括号来格式化它. 反之, 就当它有个长度为零的名字. .. code-block:: c++ - // 一行列表初始化示范。 + // 一行列表初始化示范. return {foo, bar}; functioncall({foo, bar}); pair p{foo, bar}; - // 当不得不断行时。 + // 当不得不断行时. SomeFunction( {"assume a zero-length name before {"}, some_other_function_parameter); @@ -267,14 +294,14 @@ some, other, values}}; SomeType variable{ "This is too long to fit all in one line"}; - MyType m = { // 注意了,您可以在 { 前断行。 + MyType m = { // 注意了, 您可以在 { 前断行. superlongvariablename1, superlongvariablename2, {short, interior, list}, {interiorwrappinglist, interiorwrappinglist2}}; -8.8. 条件语句 +9.9. 条件语句 ~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -287,9 +314,9 @@ .. code-block:: c++ - if (condition) { 圆括号里没空格紧邻。 - ... // 2 空格缩进。 - } else { // else 与 if 的右括号同一行。 + if (condition) { 圆括号里没空格紧邻. + ... // 2 空格缩进. + } else { // else 与 if 的右括号同一行. ... } @@ -298,8 +325,8 @@ .. code-block:: c++ if ( condition ) { // 圆括号与空格紧邻 - 不常见 - ... // 2 空格缩进。 - } else { // else 与 if 的右括号同一行。 + ... // 2 空格缩进. + } else { // else 与 if 的右括号同一行. ... } @@ -309,13 +336,13 @@ .. code-block:: c++ - if(condition) // 差 - IF 后面没空格。 - if (condition){ // 差 - { 前面没空格。 - if(condition){ // 变本加厉地差。 + if(condition) // 差 - IF 后面没空格. + if (condition){ // 差 - { 前面没空格. + if(condition){ // 变本加厉地差. .. code-block:: c++ - if (condition) { // 可 - IF 和 { 都与空格紧邻。 + if (condition) { // 可 - IF 和 { 都与空格紧邻. 如果能增强可读性, 简短的条件语句允许写在同一行. 只有当语句简单并且没有使用 ``else`` 子句时使用: @@ -339,10 +366,10 @@ .. code-block:: c++ if (condition) - DoSomething(); // 2 空格缩进。 + DoSomething(); // 2 空格缩进. if (condition) { - DoSomething(); // 2 空格缩进。 + DoSomething(); // 2 空格缩进. } 但如果语句中某个 ``if-else`` 分支使用了大括号的话, 其它分支也必须使用: @@ -351,13 +378,13 @@ .. code-block:: c++ - // 不可以这样子 - IF 有大括号 ELSE 却没有。 + // 不可以这样子 - IF 有大括号 ELSE 却没有. if (condition) { foo; } else bar; - // 不可以这样子 - ELSE 有大括号 IF 却没有。 + // 不可以这样子 - ELSE 有大括号 IF 却没有. if (condition) foo; else { @@ -367,19 +394,19 @@ .. code-block:: c++ - // 只要其中一个分支用了大括号,两个分支都要用上大括号。 + // 只要其中一个分支用了大括号, 两个分支都要用上大括号. if (condition) { foo; } else { bar; } -8.9. 循环和开关选择语句 +9.9. 循环和开关选择语句 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: - ``switch`` 语句可以使用大括号分段,以表明 cases 之间不是连在一起的。在单语句循环里,括号可用可不用。空循环体应使用 ``{}`` 或 ``continue``. + ``switch`` 语句可以使用大括号分段, 以表明 cases 之间不是连在一起的. 在单语句循环里, 括号可用可不用. 空循环体应使用 ``{}`` 或 ``continue``. ``switch`` 语句中的 ``case`` 块可以使用大括号也可以不用, 取决于你的个人喜好. 如果用的话, 要按照下文所述的方法. @@ -401,7 +428,7 @@ } } -在单语句循环里,括号可用可不用: +在单语句循环里, 括号可用可不用: .. code-block:: c++ @@ -417,18 +444,18 @@ .. code-block:: c++ while (condition) { - // 反复循环直到条件失效。 + // 反复循环直到条件失效. } - for (int i = 0; i < kSomeNumber; ++i) {} // 可 - 空循环体。 - while (condition) continue; // 可 - contunue 表明没有逻辑。 + for (int i = 0; i < kSomeNumber; ++i) {} // 可 - 空循环体. + while (condition) continue; // 可 - contunue 表明没有逻辑. .. warning:: .. code-block:: c++ - while (condition); // 差 - 看起来仅仅只是 while/loop 的部分之一。 + while (condition); // 差 - 看起来仅仅只是 while/loop 的部分之一. -8.10. 指针和引用表达式 +9.10. 指针和引用表达式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -452,11 +479,11 @@ .. code-block:: c++ - // 好样的,空格前置。 + // 好样的, 空格前置. char *c; const string &str; - // 好样的,空格后置。 + // 好样的, 空格后置. char* c; // 但别忘了 "char* c, *d, *e, ...;"! const string& str; @@ -465,11 +492,11 @@ .. code-block:: c++ char * c; // 差 - * 两边都有空格 - const string & str; // 差 - & 两边都有空格。 + const string & str; // 差 - & 两边都有空格. 在单个文件内要保持风格一致, 所以, 如果是修改现有文件, 要遵照该文件的风格. -8.11. 布尔表达式 +9.11. 布尔表达式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -486,23 +513,23 @@ ... } -注意, 上例的逻辑与 (``&&``) 操作符均位于行尾. 这格式在 Google 里很常见,您要把所有操作符放在开头也可以。可以考虑额外插入圆括号, 合理使用的话对增强可读性是很有帮助的. 此外直接用符号形式的操作符,比如 ``&&`` 和 ``~``, 不要用词语形式的 ``and`` 和 ``compl``. +注意, 上例的逻辑与 (``&&``) 操作符均位于行尾. 这格式在 Google 里很常见, 您要把所有操作符放在开头也可以. 可以考虑额外插入圆括号, 合理使用的话对增强可读性是很有帮助的. 此外直接用符号形式的操作符, 比如 ``&&`` 和 ``~``, 不要用词语形式的 ``and`` 和 ``compl``. -8.12. 函数返回值 +9.12. 函数返回值 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: - ``return`` 表达式里时没必要都用圆括号。 + ``return`` 表达式里时没必要都用圆括号. -假如您写 ``x = epr`` 时本来就会加上括号,那 ``return expr;`` 也可如法炮制。 +假如您写 ``x = epr`` 时本来就会加上括号, 那 ``return expr;`` 也可如法炮制. 函数返回时不要使用圆括号: .. code-block:: c++ - return result; // 返回值很简单,没有圆括号。 - // 可以用圆括号把复杂表达式圈起来,改善可读性。 + return result; // 返回值很简单, 没有圆括号. + // 可以用圆括号把复杂表达式圈起来, 改善可读性. return (some_long_condition && another_condition); @@ -513,7 +540,7 @@ return (value); // 毕竟您从来不会写 var = (value); return(result); // return 可不是函数! -8.13. 变量及数组初始化 +9.13. 变量及数组初始化 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -531,21 +558,21 @@ string name = "Some Name"; string name{"Some Name"}; -请务必小心列表初始化 {...} 用 ``std::initializer_list`` 构造函数初始化出的类型。非空列表初始化就会优先调用 ``std::initializer_list``, 不过空列表初始化除外,后者原则上会调用默认构造函数。为了强制禁用 ``std::initializer_list`` 构造函数,请改用括号。 +请务必小心列表初始化 {...} 用 ``std::initializer_list`` 构造函数初始化出的类型. 非空列表初始化就会优先调用 ``std::initializer_list``, 不过空列表初始化除外, 后者原则上会调用默认构造函数. 为了强制禁用 ``std::initializer_list`` 构造函数, 请改用括号. .. code-block:: c++ vector v(100, 1); // A vector of 100 1s. vector v{100, 1}; // A vector of 100, 1. -此外,列表初始化不允许整型类型的四舍五入,这可以用来避免一些类型上的编程失误。 +此外, 列表初始化不允许整型类型的四舍五入, 这可以用来避免一些类型上的编程失误. .. code-block:: c++ int pi(3.14); // 可 -- pi == 3. int pi{3.14}; // Compile error: narrowing conversion. -8.14. 预处理指令 +9.14. 预处理指令 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -558,7 +585,7 @@ // 可 - directives at beginning of line if (lopsided_score) { - #if DISASTER_PENDING // 正确 -- 行开头起。 + #if DISASTER_PENDING // 正确 -- 行开头起. DropEverything(); #endif BackToNormal(); @@ -576,7 +603,7 @@ BackToNormal(); } -8.15. 类格式 +9.15. 类格式 ~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -589,7 +616,7 @@ class MyClass : public OtherClass { public: // 注意有 1 空格缩进! - MyClass(); // 照常,2 空格缩进。 + MyClass(); // 照常, 2 空格缩进. explicit MyClass(int var); ~MyClass() {} @@ -622,7 +649,7 @@ - 关于声明顺序的规则请参考 :ref:`声明顺序 ` 一节. -8.16. 构造函数初始值列表 +9.16. 构造函数初始值列表 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -640,7 +667,7 @@ .. code-block:: c++ - // 如果要断成多行,缩进四格,冒号放在第一行初始化句: + // 如果要断成多行, 缩进四格, 冒号放在第一行初始化句: MyClass::MyClass(int var) : some_var_(var), // 4 空格缩进 some_other_var_(var + 1) { // 对准 @@ -649,7 +676,7 @@ ... } -8.17. 名字空间格式化 +9.17. 名字空间格式化 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -662,7 +689,7 @@ namespace { - void foo() { // 正确。命名空间内没有额外的缩进。 + void foo() { // 正确. 命名空间内没有额外的缩进. ... } @@ -676,21 +703,21 @@ namespace { - // 错,缩进多余了。 + // 错, 缩进多余了. void foo() { ... } } // namespace -声明嵌套命名空间时,每命名空间都独立成行。 +声明嵌套命名空间时, 每命名空间都独立成行. .. code-block:: c++ namespace foo { namespace bar { -8.18. 水平留白 +9.19. 水平留白 ~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -701,17 +728,17 @@ .. code-block:: c++ - void f(bool b) { // 左大括号前恒有空格。 + void f(bool b) { // 左大括号前恒有空格. ... - int i = 0; // 分号前不加空格。 - int x[] = { 0 }; // 大括号内部可与空格紧邻也不可,不过两边都要加上。 + int i = 0; // 分号前不加空格. + int x[] = { 0 }; // 大括号内部可与空格紧邻也不可, 不过两边都要加上. int x[] = {0}; - // 继承与初始化列表中的冒号前后恒有空格。 + // 继承与初始化列表中的冒号前后恒有空格. class Foo : public Bar { public: - // 至于内联函数实现,在大括号内部加上空格并编写实现。 - Foo(int b) : Bar(), baz_(b) {} // 大括号里面是空的话,不加空格。 - void Reset() { baz_ = 0; } // 用括号把大括号与实现分开。 + // 至于内联函数实现, 在大括号内部加上空格并编写实现. + Foo(int b) : Bar(), baz_(b) {} // 大括号里面是空的话, 不加空格. + void Reset() { baz_ = 0; } // 用括号把大括号与实现分开. ... 添加冗余的留白会给其他人编辑时造成额外负担. 因此, 行尾不要留空格. 如果确定一行代码已经修改完毕, 将多余的空格去掉; 或者在专门清理空格时去掉(确信没有其他人在处理). (Yang.Y 注: 现在大部分代码编辑器稍加设置后, 都支持自动删除行首/行尾空格, 如果不支持, 考虑换一款编辑器或 IDE) @@ -720,35 +747,35 @@ .. code-block:: c++ - if (b) { // if 条件语句和循环语句关键字后均有空格。 - } else { // else 前后有空格。 + if (b) { // if 条件语句和循环语句关键字后均有空格. + } else { // else 前后有空格. } - while (test) {} // 圆括号内部不紧邻空格。 + while (test) {} // 圆括号内部不紧邻空格. switch (i) { for (int i = 0; i < 5; ++i) { - switch ( i ) { // 循环和条件语句的圆括号里可以与空格紧邻。 - if ( test ) { // 圆括号,但这很少见。总之要一致。 + switch ( i ) { // 循环和条件语句的圆括号里可以与空格紧邻. + if ( test ) { // 圆括号, 但这很少见. 总之要一致. for ( int i = 0; i < 5; ++i ) { - for ( ; i < 5 ; ++i) { // 循环里内 ; 后恒有空格,; 前可以加个空格。 + for ( ; i < 5 ; ++i) { // 循环里内 ; 后恒有空格, ; 前可以加个空格. switch (i) { - case 1: // switch case 的冒号前无空格。 + case 1: // switch case 的冒号前无空格. ... - case 2: break; // 如果冒号有代码,加个空格。 + case 2: break; // 如果冒号有代码, 加个空格. 操作符: .. code-block:: c++ - // 赋值操作系统前后恒有空格。 + // 赋值操作系统前后恒有空格. x = 0; - // 其它二元操作符也前后恒有空格,不过对 factors 前后不加空格也可以。 - // 圆括号内部不紧邻空格。 + // 其它二元操作符也前后恒有空格, 不过对 factors 前后不加空格也可以. + // 圆括号内部不紧邻空格. v = w * x + y / z; v = w*x + y/z; v = w * (x + z); - // 在参数和一元操作符之间不加空格。 + // 在参数和一元操作符之间不加空格. x = -5; ++x; if (x && !y) @@ -758,19 +785,19 @@ .. code-block:: c++ - // 尖叫括号(< and >) 不与空格紧邻,< 前没有空格,>( 之间也没有。 + // 尖叫括号(< and >) 不与空格紧邻, < 前没有空格, >( 之间也没有. vector x; y = static_cast(x); - // 在类型与指针操作符之间留空格也可以,但要保持一致。 + // 在类型与指针操作符之间留空格也可以, 但要保持一致. vector x; - set> x; // 在 C++11 代码里可以这样用了。 - set > x; // C++03 中要在 > > 里留个空格。 + set> x; // 在 C++11 代码里可以这样用了. + set > x; // C++03 中要在 > > 里留个空格. - // 您或许可以在 < < 里加上一对对称的空格。 + // 您或许可以在 < < 里加上一对对称的空格. set< list > x; -8.19. 垂直留白 +9.19. 垂直留白 ~~~~~~~~~~~~~~~~~~~~~~~~ .. tip:: @@ -783,8 +810,8 @@ 空行心得如下: -* 函数体内开头或结尾的空行可读性微乎其微。 -* 在多重 if-else 块里加空行或许有点可读性。 +* 函数体内开头或结尾的空行可读性微乎其微. +* 在多重 if-else 块里加空行或许有点可读性. 译者 (YuleFox) 笔记 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -805,11 +832,11 @@ 译者(acgtyrant)笔记 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -#. 80 行限制事实上有助于避免代码可读性失控,比如超多重嵌套块,超多重函数调用等等。 -#. Linux 上设置好了 Locale 就几乎一劳永逸设置好所有开发环境的编码,不像奇葩的 Windows. -#. Google 强调有一对 if-else 时,不论有没有嵌套,都要有大括号。Apple 正好 `有栽过跟头 `_ . -#. 其实我主张指针/地址操作符与变量名紧邻,``int* a, b`` vs ``int *a, b``, 新手会误以为前者的 ``b`` 是 ``int *`` 变量,但后者就不一样了,高下立判。 -#. 在这风格指南里我才刚知道 C++ 原来还有所谓的 `Alternative operator representations `_, 大概没人用吧。 -#. 注意构造函数初始值列表(Constructer Initializer List)与列表初始化(Initializer List)是两码事,我就差点混淆了它们的翻译。 -#. 事实上,如果您熟悉英语本身的书写规则,就会发现该风格指南在格式上的规定与英语语法相当一脉相承。比如普通标点符号和单词后面还有文本的话,总会留一个空格;特殊符号与单词之间就不用留了,比如 ``if (true)`` 中的圆括号与 ``true``. -#. 本风格指南没有明确规定 void 函数里要不要用 return 语句,不过就 Google 开源项目 leveldb 并没有写;此外从 `Is a blank return statement at the end of a function whos return type is void necessary? `_ 来看,``return;`` 比 ``return ;`` 更约定俗成(事实上 cpplint 会对后者报错,指出分号前有多余的空格),且可用来提前跳出函数栈。 +#. 80 行限制事实上有助于避免代码可读性失控, 比如超多重嵌套块, 超多重函数调用等等. +#. Linux 上设置好了 Locale 就几乎一劳永逸设置好所有开发环境的编码, 不像奇葩的 Windows. +#. Google 强调有一对 if-else 时, 不论有没有嵌套, 都要有大括号. Apple 正好 `有栽过跟头 `_ . +#. 其实我主张指针/地址操作符与变量名紧邻, ``int* a, b`` vs ``int *a, b``, 新手会误以为前者的 ``b`` 是 ``int *`` 变量, 但后者就不一样了, 高下立判. +#. 在这风格指南里我才刚知道 C++ 原来还有所谓的 `Alternative operator representations `_, 大概没人用吧. +#. 注意构造函数初始值列表(Constructer Initializer List)与列表初始化(Initializer List)是两码事, 我就差点混淆了它们的翻译. +#. 事实上, 如果您熟悉英语本身的书写规则, 就会发现该风格指南在格式上的规定与英语语法相当一脉相承. 比如普通标点符号和单词后面还有文本的话, 总会留一个空格; 特殊符号与单词之间就不用留了, 比如 ``if (true)`` 中的圆括号与 ``true``. +#. 本风格指南没有明确规定 void 函数里要不要用 return 语句, 不过就 Google 开源项目 leveldb 并没有写; 此外从 `Is a blank return statement at the end of a function whos return type is void necessary? `_ 来看, ``return;`` 比 ``return ;`` 更约定俗成(事实上 cpplint 会对后者报错, 指出分号前有多余的空格), 且可用来提前跳出函数栈. From 4d5021621e265b868aa3af0db8607018c6b08072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=87=8C?= Date: Wed, 19 Apr 2017 14:26:11 +0800 Subject: [PATCH 7/8] Ling.Li: Fix a typo. --- google-cpp-styleguide/formatting.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cpp-styleguide/formatting.rst b/google-cpp-styleguide/formatting.rst index 7cb0d59..f8a4517 100644 --- a/google-cpp-styleguide/formatting.rst +++ b/google-cpp-styleguide/formatting.rst @@ -45,7 +45,7 @@ 即使是英文, 也不应将用户界面的文本硬编码到源代码中, 因此非 ASCII 字符应当很少被用到. 特殊情况下可以适当包含此类字符. 例如, 代码分析外部数据文件时, 可以适当硬编码数据文件中作为分隔符的非 ASCII 字符串; 更常见的是 (不需要本地化的) 单元测试代码可能包含非 ASCII 字符串. 此类情况下, 应使用 UTF-8 编码, 因为很多工具都可以理解和处理 UTF-8 编码. -十六进制编码也可以, 能增强可读性的情况下尤其鼓励 —— 比如 ``"\xEF\xBB\xBF"`, 或者更简洁地写作 ``u8"\uFEFF"``, 在 Unicode 中是 *零宽度 无间断* 的间隔符号, 如果不用十六进制直接放在 UTF-8 格式的源文件中, 是看不到的. +十六进制编码也可以, 能增强可读性的情况下尤其鼓励 —— 比如 ``"\xEF\xBB\xBF"``, 或者更简洁地写作 ``u8"\uFEFF"``, 在 Unicode 中是 *零宽度 无间断* 的间隔符号, 如果不用十六进制直接放在 UTF-8 格式的源文件中, 是看不到的. (Yang.Y 注: ``"\xEF\xBB\xBF"`` 通常用作 UTF-8 with BOM 编码标记) From a42301f98d324b7230edf6fdd2a4aaf80d432f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=87=8C?= Date: Wed, 19 Apr 2017 14:28:07 +0800 Subject: [PATCH 8/8] Ling.Li: Remove indents in Chapter 10. --- google-cpp-styleguide/exceptions.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/google-cpp-styleguide/exceptions.rst b/google-cpp-styleguide/exceptions.rst index bb0df0c..3e83c70 100644 --- a/google-cpp-styleguide/exceptions.rst +++ b/google-cpp-styleguide/exceptions.rst @@ -27,23 +27,23 @@ Windows 程序员有自己的编程习惯, 主要源于 Windows 头文件和其 如果你习惯使用 Windows 编码风格, 这儿有必要重申一下某些你可能会忘记的指南: - - 不要使用匈牙利命名法 (比如把整型变量命名成 ``iNum``). 使用 Google 命名约定, 包括对源文件使用 ``.cc`` 扩展名. +- 不要使用匈牙利命名法 (比如把整型变量命名成 ``iNum``). 使用 Google 命名约定, 包括对源文件使用 ``.cc`` 扩展名. - - Windows 定义了很多原生类型的同义词 (YuleFox 注: 这一点, 我也很反感), 如 ``DWORD``, ``HANDLE`` 等等. 在调用 Windows API 时这是完全可以接受甚至鼓励的. 即使如此, 还是尽量使用原有的 C++ 类型, 例如使用 ``const TCHAR *`` 而不是 ``LPCTSTR``. +- Windows 定义了很多原生类型的同义词 (YuleFox 注: 这一点, 我也很反感), 如 ``DWORD``, ``HANDLE`` 等等. 在调用 Windows API 时这是完全可以接受甚至鼓励的. 即使如此, 还是尽量使用原有的 C++ 类型, 例如使用 ``const TCHAR *`` 而不是 ``LPCTSTR``. - - 使用 Microsoft Visual C++ 进行编译时, 将警告级别设置为 3 或更高, 并将所有警告(warnings)当作错误(errors)处理. +- 使用 Microsoft Visual C++ 进行编译时, 将警告级别设置为 3 或更高, 并将所有警告(warnings)当作错误(errors)处理. - - 不要使用 ``#pragma once``; 而应该使用 Google 的头文件保护规则. 头文件保护的路径应该相对于项目根目录 (Yang.Y 注: 如 ``#ifndef SRC_DIR_BAR_H_``, 参考 :ref:`#define 保护 ` 一节). +- 不要使用 ``#pragma once``; 而应该使用 Google 的头文件保护规则. 头文件保护的路径应该相对于项目根目录 (Yang.Y 注: 如 ``#ifndef SRC_DIR_BAR_H_``, 参考 :ref:`#define 保护 ` 一节). - - 除非万不得已, 不要使用任何非标准的扩展, 如 ``#pragma`` 和 ``__declspec``. 使用 ``__declspec(dllimport)`` 和 ``__declspec(dllexport)`` 是允许的, 但必须通过宏来使用, 比如 ``DLLIMPORT`` 和 ``DLLEXPORT``, 这样其他人在分享使用这些代码时可以很容易地禁用这些扩展. +- 除非万不得已, 不要使用任何非标准的扩展, 如 ``#pragma`` 和 ``__declspec``. 使用 ``__declspec(dllimport)`` 和 ``__declspec(dllexport)`` 是允许的, 但必须通过宏来使用, 比如 ``DLLIMPORT`` 和 ``DLLEXPORT``, 这样其他人在分享使用这些代码时可以很容易地禁用这些扩展. 然而, 在 Windows 上仍然有一些我们偶尔需要违反的规则: - - 通常我们 :ref:`禁止使用多重继承 `, 但在使用 COM 和 ATL/WTL 类时可以使用多重继承. 为了实现 COM 或 ATL/WTL 类/接口, 你可能不得不使用多重实现继承. +- 通常我们 :ref:`禁止使用多重继承 `, 但在使用 COM 和 ATL/WTL 类时可以使用多重继承. 为了实现 COM 或 ATL/WTL 类/接口, 你可能不得不使用多重实现继承. - - 虽然代码中不应该使用异常, 但是在 ATL 和部分 STL(包括 Visual C++ 的 STL) 中异常被广泛使用. 使用 ATL 时, 应定义 ``_ATL_NO_EXCEPTIONS`` 以禁用异常. 你需要研究一下是否能够禁用 STL 的异常, 如果无法禁用, 可以启用编译器异常. (注意这只是为了编译 STL, 自己的代码里仍然不应当包含异常处理). +- 虽然代码中不应该使用异常, 但是在 ATL 和部分 STL(包括 Visual C++ 的 STL) 中异常被广泛使用. 使用 ATL 时, 应定义 ``_ATL_NO_EXCEPTIONS`` 以禁用异常. 你需要研究一下是否能够禁用 STL 的异常, 如果无法禁用, 可以启用编译器异常. (注意这只是为了编译 STL, 自己的代码里仍然不应当包含异常处理). - - 通常为了利用头文件预编译, 每个每个源文件的开头都会包含一个名为 ``StdAfx.h`` 或 ``precompile.h`` 的文件. 为了使代码方便与其他项目共享, 请避免显式包含此文件 (除了在 ``precompile.cc`` 中), 使用 ``/FI`` 编译器选项以自动包含该文件. +- 通常为了利用头文件预编译, 每个每个源文件的开头都会包含一个名为 ``StdAfx.h`` 或 ``precompile.h`` 的文件. 为了使代码方便与其他项目共享, 请避免显式包含此文件 (除了在 ``precompile.cc`` 中), 使用 ``/FI`` 编译器选项以自动包含该文件. - - 资源头文件通常命名为 ``resource.h`` 且只包含宏, 这一文件不需要遵守本风格指南. +- 资源头文件通常命名为 ``resource.h`` 且只包含宏, 这一文件不需要遵守本风格指南.