C++ 使用规范

解释

从 Godot 4.0 开始,代码库中所使用的 C++ 标准是 C++17 的子集。现代 C++ 带来了许多机会,让我们能够编写更快、更易读的代码,但我们选择将我们对 C++ 的使用限制在一个子集中,原因有这么几点:

  • 易于使用在线编辑器审核代码。这是因为引擎的贡献者在审核代码时并不总是可以使用完整的 IDE。

  • 易于让新手贡献者掌握代码(他们可能不是专业的 C++ 程序员)。Godot 的代码库是公认的易于学习,我们希望继续保持。

要让你的拉取请求被合并,就需要遵守这里描述的 C++ 使用规范。当然,在你自己的 C++ 模块或 GDNative 脚本中是可以使用此处禁止的特性的。

备注

在 Godot 4.0 之前的版本中,代码库所使用的 C++ 标准曾是 C++03,外加一些 C++14 扩展。如果你是在为 3.x 分支提交拉取请求而不是 master,就不能使用 C++17 的特性。请确保你的代码能够使用 C++14 编译器构建。

以下规范并不适用于第三方依赖,虽然我们一般倾向于使用小型的库而不是大型的解决方案。另请参阅 引擎贡献者的最佳实践

参见

格式化规范请参阅 代码风格规范

禁用的特性

未在下方列出的特性都是允许的。鼓励尽可能使用 constexpr 变量和 nullptr 等特性。不过请您在使用现代 C++ 特性时保持保守。使用时应当为实际的目的服务,例如提升代码可读性或性能。

标准模板库

我们不允许使用 STL,因为 Godot 提供了自有的数据类型(及其他工具)。详情请参阅 为什么 Godot 不使用 STL(标准模板库)?

这意味着拉取请求中不应该使用 std::stringstd::vector 等工具。请使用如下所述的 Godot 数据类型代替:

  • 使用 String 代替 std::string

  • Use Vector instead of std::vector. In some cases, LocalVector can be used as an alternative (ask core developers first).

  • 使用 Array 代替 std::array

备注

Godot also has a List datatype (which is a linked list). While List is already used in the codebase, it typically performs worse than other datatypes like Vector and Array. Therefore, List should be avoided in new code unless necessary.

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 的排序规范请参阅 标头引入