C++ 使用规范
依据
从 Godot 4.0 开始,代码库中所使用的 C++ 标准是 C++17 的子集。现代 C++ 带来了许多机会,让我们能够编写更快、更易读的代码,但我们选择将我们对 C++ 的使用限制在一个子集中,原因有这么几点:
易于使用在线编辑器审核代码。这是因为引擎的贡献者在审核代码时并不总是可以使用完整的 IDE。
易于让新手贡献者掌握代码(他们可能不是专业的 C++ 程序员)。Godot 的代码库是公认的易于学习,我们希望继续保持。
To get your pull request merged, it needs to follow the C++ usage guidelines outlined here. Of course, you can use features not allowed here in your own C++ modules or GDExtensions.
备注
在 Godot 4.0 之前的版本中,代码库所使用的 C++ 标准曾是 C++03,外加一些 C++14 扩展。如果你是在为 3.x 分支提交拉取请求而不是 master,就不能使用 C++17 的特性。请确保你的代码能够使用 C++14 编译器构建。
以下规范并不适用于第三方依赖,虽然我们一般倾向于使用小型的库而不是大型的解决方案。另请参阅 引擎贡献者的最佳实践。
参见
格式化规范请参阅 代码风格规范。
禁用的特性
未在下方列出的特性都是允许的。鼓励尽可能使用 constexpr
变量和 nullptr
等特性。不过请你在使用现代 C++ 特性时保持保守。使用时应当为实际的目的服务,例如提升代码可读性或性能。
标准模板库
我们不允许使用 STL,因为 Godot 提供了自有的数据类型(及其他工具)。详情请参阅 为什么 Godot 不使用 STL(标准模板库)?。
这意味着拉取请求中不应该使用 std::string
、std::vector
等工具。请使用如下所述的 Godot 数据类型代替:
使用
String
代替std::string
。使用
Vector
代替std::vector
。某些情况下也可以用LocalVector
代替(请先咨询核心开发者)。使用
Array
代替std::array
。
备注
Godot 还有一个 List 数据类型(是个链表)。虽然 List 在代码库中有所使用,但一般性能都比 Vector 和 Array 等数据类型要差。因此,除非必要,否则应该避免在新代码中使用 List。
auto
关键字
请勿使用 auto
关键字进行类型推导。虽然可以避免重复,但也可能导致令人费解的代码:
// Not so confusing...
auto button = memnew(Button);
// ...but what about this?
auto result = EditorNode::get_singleton()->get_complex_result();
请记住,拉取请求的审核者一般是没有悬停文档的。大多数情况下,审核者是用 GitHub 的在线查看器审核拉取请求的。
为了避免需要在难以抉择的极端情况上下定论的情况发生,我们选择禁止 auto
,不允许特事特办。感谢你的理解。
Lambda
应该保守地使用 lambda,需要在能让代码更快或者更简单的同时,不妨碍可读性。请在拉取请求中使用 lambda 前先询问。
#pragma once
指令
为了遵循现有风格,请在新文件中使用标准的基于 #ifdef
的包含保护,不要使用 #pragma once
。
参见
C++ 和 Objective-C 文件中 include 的排序规范请参阅 头文件的引入。