コンテンツにスキップ

04.C++ コーディング規約

このドキュメントでは、DevBlueprintを利用するプロジェクトでC++を記述する際の、コーディングスタイルと規約について定めます。 モダンC++ (C++17以降) の機能を活用し、安全性と保守性の高いコードを目指します。

共通原則およびC言語規約との関係


1. 基本方針: C++ Core Guidelines 準拠

  • 本プロジェクトのC++コードは、Bjarne Stroustrupらが主導するC++ Core Guidelinesの思想に準拠することを目指します。
  • 全てのルールを厳密に適用するわけではありませんが、このガイドラインは「モダンC++における良いコードとは何か」を知るための、最も信頼できる情報源です。

2. 自動フォーマットと静的解析

C言語規約と同様に、ツールの利用を強く推奨します。

  • フォーマッター: ClangFormat
    • .clang-formatファイルでプロジェクトのスタイルを定義し、コードの見た目を統一します。
  • 静的解析: Clang-Tidy, MSVCの静的解析など
    • 潜在的なバグ、リソースリーク、ガイドライン違反などを自動で検出します。CI/CDへの統合を強く推奨します。

3. モダンC++のベストプラクティス (C++17以降)

3.1. リソース管理: RAIIとスマートポインタ

  • RAII (Resource Acquisition Is Initialization) の原則を徹底します。リソース(メモリ、ファイル、ソケット等)は、その生存期間を管理するオブジェクト(クラス)のコンストラクタで取得し、デストラクタで解放します。
  • 手動でのnew/deleteは原則として禁止します。
  • メモリ管理には、以下のスマートポインタを必ず使用してください。
    • std::unique_ptr: リソースの唯一の所有権を示す場合の第一選択。
    • std::shared_ptr: 複数のポインタがリソースの所有権を共有する場合。
    • std::make_unique / std::make_shared: スマートポインタを作成する際は、これらのヘルパー関数を使用します。

3.2. 推奨される言語機能

  • autoキーワード: 型が右辺から自明な場合や、イテレータなどの複雑な型を扱う場合は、autoを積極的に利用し、コードの冗長性を減らします。
  • 範囲ベースforループ: コンテナの全要素を走査する場合は、インデックスベースの古いforループではなく、範囲ベースforループを使用します。
    // 良い例
    for (const auto& item : my_vector) {
        // ...
    }
    
  • nullptrの使用: ヌルポインターを示す場合は、C言語由来のNULLマクロではなく、型安全なnullptrを必ず使用します。
  • constconstexpr: 変更しない変数にはconstを、コンパイル時定数にはconstexprを積極的に利用し、不変性(Immutability)を高めます。
  • enum classの使用: 型安全でない古いenumではなく、スコープを持ち、暗黙的な整数変換のないenum classを使用します。

3.3. クラス設計

  • overridefinal: 仮想関数をオーバーライドする際はoverrideキーワードを、これ以上派生させないクラスや仮想関数にはfinalキーワードを明記します。
  • defaultdelete: コンパイラが自動生成する特殊なメンバー関数を明示的にデフォルト実装させたい場合は= default;を、禁止したい場合は= delete;を使用します。

4. 要求IDとの連携

  • 01.共通コーディング原則 で定められた通り、機能の実装に対応する要求IDを、クラスやメソッドのコメントとして明記します。

    // REQ-GPU-2.1: CUDAストリームを作成し、非同期カーネル実行を管理する
    class CudaStreamManager final {
    public:
        CudaStreamManager() = default;
        ~CudaStreamManager() = default;
    
        // ...
    };