C++ 使用規範

說明

自 Godot 4.0 起,整個程式碼庫採用的是 C++17 標準的子集。現代 C++ 雖帶來許多讓程式碼更高效、易讀的機會,但我們基於以下幾點決定僅採用部份語法:

  • 讓線上編輯器審查程式碼更容易。這是因為引擎貢獻者審查程式碼時,不一定能使用完整功能的 IDE。

  • 讓新手貢獻者(即使不是專業 C++ 程式設計師)也能更容易理解程式碼。Godot 的程式碼庫向來以易於學習聞名,我們希望保持這樣的特性。

要讓你的拉取請求被合併,必須遵循本文件描述的 C++ 使用規範。當然,你可以在自己的 C++ 模組或 GDExtension 中使用這裡未允許的功能。

備註

在 Godot 4.0 之前,程式碼庫主要採用 C++03 標準,並搭配部分 C++14 擴充。如果你是為 3.x 分支(而非 master)提交拉取請求,則不能使用 C++17 功能,你的程式碼必須能用 C++14 編譯器建構。

以下規範不適用於協力廠商相依庫,雖然我們一般偏好小型函式庫而非大型解決方案。另請參閱 引擎貢獻者最佳實踐

也參考

格式化規範請參見 程式碼樣式方針

不允許的功能

未在下方列出的功能皆為允許。 建議盡量使用 constexpr 變數、nullptr 等現代 C++ 特性。不過,請儘量保守使用新語法,並確保其用途能實質改善程式碼可讀性或效能。

標準模板函式庫(STL)

我們不允許使用 STL,因為 Godot 有自行提供的資料型別(及其他工具)。詳見 為什麼Godot不使用STL(Standard Template Library)?

這代表拉取請求中**不得**使用 std::stringstd::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();

請記住,拉取請求的審查者大多無法即時取得 hover 文件。通常審查者是用 GitHub 線上檢視器來審查拉取請求。

我們選擇全面禁止 auto,而不是視情況允許,以免遇到難以界定的極端案例。感謝您的理解。

Lambda 函式

Lambda 僅應在確實能讓程式碼更快或更簡潔,且不影響可讀性的情況下保守使用。若要在拉取請求中用 lambda,請先徵詢意見。

#pragma once 指令

為了遵循現有風格,請於新檔案使用標準的 #ifdef 方式作為包含保護,不要使用 #pragma once

try-catch 區塊

禁止使用 C++ 風格的 trycatch 例外處理區塊。這項限制是基於效能、執行檔大小,以及程式碼複雜度等多重考量。請改用 錯誤巨集 所述方法。

也參考

C++ 與 Objective-C 檔案的 include 排序規範,請見 標頭檔引用