# C++ コーディング規約 ## 1. 一般的なガイドライン 1. **モダン C++(C++17 以上)** を前提とする。 2. 生ポインタより、まず **`std::unique_ptr` / `std::shared_ptr` / `std::vector` など RAII** を優先する。 3. 例外を使う場合は、**例外 or エラーコードのどちらかに統一**する。 4. `new` / `delete` は基本的に直接使わず、スマートポインタやコンテナを使う。 5. ヘッダ/ソース分割は `*.h` / `*.cpp`(または `*.hpp` / `*.cpp`)で行う。 6. 自動整形には **`clang-format`** を利用する。 --- ## 2. コメント/ドキュメント ### 2.1 ファイルコメント ```cpp // user_service.h - ユーザー関連のユースケースを提供するクラス群 #pragma once // ... ``` ### 2.2 クラスコメント(Doxygen 推奨) ```cpp /** * @brief ユーザーを管理するサービスクラス。 * * ユーザーの作成、取得、削除などの機能を提供する。 */ class UserService { public: /// コンストラクタ explicit UserService(UserRepository& repo); /// ユーザーを作成する User createUser(const std::string& name, int age); private: UserRepository& repo_; }; ``` ### 2.3 メソッドコメント ```cpp /** * @brief ユーザーをIDで取得する。 * * @throws std::runtime_error ユーザーが存在しない場合。 */ User UserService::getUserById(int id); ``` --- ## 3. 命名規則 1. **クラス名/構造体名**: `CamelCase` ```cpp class UserService; struct HttpRequest; ``` 2. **メソッド・関数名**: `camelCase` または `snake_case`(プロジェクト内で統一) ```cpp void addUser(const User& user); int find_user(const std::string& name); // プロジェクト方針次第 ``` 3. **メンバ変数**: * プレフィックスやサフィックスを付けるスタイルが多い 例: `snake_case_` / `m_name` / `_name` など ```cpp class User { public: explicit User(std::string name, int age) : name_(std::move(name)), age_(age) {} private: std::string name_; int age_; }; ``` 4. **定数**: * グローバル定数には `k` プレフィックスを使う場合も多い。 ```cpp constexpr int kMaxUserCount = 1000; ``` 5. **名前空間**: すべて小文字でプロジェクト名などを使う。 ```cpp namespace myapp::user { // ... } ``` --- ## 4. インクルードガイドライン 1. ヘッダでのインクルードは **最小限** にする。前方宣言で済むなら前方宣言を使う。 ```cpp // user_service.h #pragma once #include namespace myapp { class UserRepository; // 前方宣言 class UserService { public: explicit UserService(UserRepository& repo); // ... private: UserRepository& repo_; }; } // namespace myapp ``` 2. ソースファイルでは対応するヘッダをまずインクルードし、その後に標準/外部ライブラリ。 ```cpp // user_service.cpp #include "user_service.h" #include "user_repository.h" #include ``` 3. インクルード順は以下を推奨: 1. 自分のヘッダ 2. 同じモジュールのヘッダ 3. 標準ライブラリ 4. サードパーティヘッダ --- ## 5. エラーハンドリング ### 5.1 例外を使う場合 1. ロジック上の失敗には `throw` で例外を投げ、呼び出し側で `try`/`catch`。 ```cpp User UserService::getUserById(int id) { auto user = repo_.findById(id); if (!user) { throw std::runtime_error("User not found"); } return *user; } ``` 2. 例外の種類は、`std::runtime_error` / `std::invalid_argument` などを使い分ける。 3. ライブラリ側では「例外を投げる API」と「エラーコードを返す API」を明確に分ける。 ### 5.2 例外を使わない場合 1. 戻り値に `std::optional` や `expected` パターン(独自実装)を使う。 ```cpp std::optional UserService::tryGetUserById(int id) { return repo_.findById(id); } ``` --- ## 6. 複数ファイル間の分割(ヘッダ / ソース) ### 6.1 例: User と UserService ```text include/ user.h user_service.h src/ user.cpp user_service.cpp main.cpp ``` #### `user.h` ```cpp #pragma once #include namespace myapp { class User { public: User(int id, std::string name); int id() const; const std::string& name() const; private: int id_; std::string name_; }; } // namespace myapp ``` #### `user.cpp` ```cpp #include "user.h" namespace myapp { User::User(int id, std::string name) : id_(id), name_(std::move(name)) { } int User::id() const { return id_; } const std::string& User::name() const { return name_; } } // namespace myapp ``` #### `user_service.h` ```cpp #pragma once #include #include "user.h" namespace myapp { class UserRepository; class UserService { public: explicit UserService(UserRepository& repo); User createUser(const std::string& name, int age); private: UserRepository& repo_; }; } // namespace myapp ``` #### `user_service.cpp` ```cpp #include "user_service.h" #include "user_repository.h" namespace myapp { UserService::UserService(UserRepository& repo) : repo_(repo) { } User UserService::createUser(const std::string& name, int age) { // 仮実装: ID採番して保存するなど int newId = repo_.nextId(); User user(newId, name); repo_.save(user); return user; } } // namespace myapp ``` --- ## 7. clang-format / clang-tidy / VSCode 設定 ### 7.1 `.clang-format`(C と共有してもOK) ```yaml BasedOnStyle: LLVM IndentWidth: 4 UseTab: Never ColumnLimit: 100 AllowShortIfStatementsOnASingleLine: false BreakBeforeBraces: Attach NamespaceIndentation: All ``` ### 7.2 VSCode 設定例 ```json { "[cpp]": { "editor.defaultFormatter": "ms-vscode.cpptools", "editor.formatOnSave": true }, "C_Cpp.clang_format_style": "file", // clang-tidy を使う場合 "C_Cpp.codeAnalysis.clangTidy.enabled": true, "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true } ```