Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
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(标准模板库)?。
This means that pull requests should not use std::string
,
std::vector
and the like. Instead, use Godot's datatypes as described in
the 核心类型 documentation.
A 📜 icon denotes the type is part of Variant. This means it can be used as a parameter or return value of a method exposed to the scripting API.
auto
关键字
请勿使用 auto
关键字进行类型推导。虽然可以避免重复,但也可能导致令人费解的代码:
// Not so confusing...
auto button = memnew(Button);
// ...but what about this?
auto result = EditorNode::get_singleton()->get_complex_result();
请记住,拉取请求的审核者一般是没有悬停文档的。大多数情况下,审核者是用 GitHub 的在线查看器审核拉取请求的。
The auto
keyword can be used in some special cases, like C++ lambda or Objective-C block
definitions and C++ templates. Please ask before using templates with auto
in a pull request.
// Full type definitions.
void (*mult64to128)(uint64_t, uint64_t, uint64_t &, uint64_t &) = [](uint64_t u, uint64_t v, uint64_t &h, uint64_t &l) { ... }
void (^JOYSTICK_LEFT)(GCControllerDirectionPad *__strong, float, float) = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { ... }
// Less clutter with auto.
auto mult64to128 = [](uint64_t u, uint64_t v, uint64_t &h, uint64_t &l) { ... }
auto JOYSTICK_LEFT = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { ... }
// Compare function for different types.
template <typename T1, typename T2>
constexpr auto MIN(const T1 m_a, const T2 m_b) {
return m_a < m_b ? m_a : m_b;
}
We chose to forbid auto
in all other cases. Thank you for your understanding.
Lambda
应该保守地使用 lambda,需要在能让代码更快或者更简单的同时,不妨碍可读性。请在拉取请求中使用 lambda 前先询问。
#ifdef
-based include guards
Starting with 4.5, all files now use the #pragma once
directive, as they
improve readability and declutter macros. Use of #ifdef
-based include
guards are now actively discouraged.
try
-catch
代码块
禁止使用 try
和 catch
块进行 C++ 风格的异常处理。这一限制基于多个原因,包括性能、二进制文件大小和代码复杂性。请改用 错误宏。
参见
C++ 和 Objective-C 文件中 include 的排序规范请参阅 头文件的引入。