C++ Academy · レッスン

スコープガード

スコープ終了時にクリーンアップを実行します

レッスン 4/413 ステップ

「スコープガード」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

スコープガードとは

スコープガードは、スコープを抜けるときにクリーンアップ処理を実行することだけを目的としたRAIIオブジェクトです。早期のreturnや例外が発生した場合にも実行されます。

解決する問題

ガードがないと、早期のreturnやthrowの後に行うクリーンアップを忘れやすくなります。スコープガードを使えば、その処理を自動化できます。

lock_guard: 標準のスコープガード

std::lock_guardは構築時にミューテックスをロックし、破棄時にアンロックします。ロック用の組み込みスコープガードです。

#include <mutex>

std::mutex m;

void critical() {
    std::lock_guard<std::mutex> lk(m);   // locked
    // ... work ...
}                                        // unlocked automatically

自作のガード

関数を保持し、デストラクタでその関数を呼び出すガードを作成できます。

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "cleanup\n"; });
    std::cout << "work\n";
}

早期リターンでもクリーンアップされる

デストラクタはスコープの終了時に呼び出されるため、関数がどのように終了しても、ガードの処理が実行されます。

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

void run(bool stop) {
    ScopeGuard g([] { std::cout << "always cleaned\n"; });
    if (stop) return;
}

int main() { run(true); }

例外発生時でもクリーンアップされる

例外によってスコープが巻き戻される場合でも、ガードのデストラクタは実行され、リソースを安全に解放します。

ガードのキャンセル

クリーンアップを省略したい場合もあります(操作が成功した場合など)。実際のガードには、処理を無効にするdismiss()が用意されています。

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
    bool active = true;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    void dismiss() { active = false; }
    ~ScopeGuard() { if (active) fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "rollback\n"; });
    g.dismiss();   // success: no rollback
}

ロールバックに使う

スコープガードはトランザクション処理で特に役立ちます。ロールバック処理を登録して作業を行い、成功したらガードをdismiss()します。

ガードはムーブ専用にする

ガードはコピーできないようにするべきです。コピーすると処理が2回実行されてしまいます。ガードはムーブ専用またはコピー不可にしてください。

標準およびライブラリのヘルパー

std::scoped_lockは複数のミューテックスを保護し、GSLなどのライブラリはfinallyを提供します。多くのコードベースでは、小規模なScopeGuardユーティリティを用意しています。

専用のRAII型を優先する

専用のRAII型(lock_guard、unique_ptr、fstream)がある場合は、それを優先してください。自然なラッパーがない、その場限りのクリーンアップにだけ、汎用スコープガードを使います。

クイックチェック

スコープガードの理解度を確認しましょう。

まとめ

スコープガードは、RAIIによってスコープ終了時のクリーンアップを自動的に実行することを学びました。早期リターンや例外に対応し、dismiss()によるロールバックにも対応できます。また、ムーブ専用にするべきです。専用のRAII型がある場合は、それを優先してください。

無料で開始

AI チューターと学ぶ C++ — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
51
レッスン
203

よくある質問

「スコープガード」レッスンは無料ですか?

はい。「スコープガード」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「スコープガード」で何を学びますか?

スコープ終了時にクリーンアップを実行します ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「スコープガード」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. RAII原則
  2. デストラクタとクリーンアップ
  3. Rule of Three/Five
  4. スコープガード
← C++ Academyに戻る