スコープガード
スコープ終了時にクリーンアップを実行します
「スコープガード」は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フィードバックを取得できます。ローカル設定は不要です。