SlideShare ist ein Scribd-Unternehmen logo
1 von 10
Downloaden Sie, um offline zu lesen
メンバ変数のメンバ関数内での
    リソース管理


        高橋晶(Akira Takahashi)
            id:faith_and_brave
                    @cpp_akira
        Boost.勉強会 #8 大阪 2012/02/11(土)
RAII
• C++には、RAII(Resource Acquisition Is Initialization:リソース
  確保は初期化である)というイディオムがある。
• 簡単に言えば、確保したリソースはデストラクタで自動的に
  解放する、というもの。

void f()
{
    File file;
    file.open("a.txt");

    if (!file.write("xxxxxxxx")) {
        return; // 途中で抜けてもファイルは閉じられる
    }
} // ファイルが閉じられる

• これはローカル変数には非常に有効。
メンバ変数のリソース管理
• メンバ変数の寿命がクラスと同じでよければ、RAIIが有用。

class X {
    std::vector<User> users;

public:
    ~X()
    {
    } // ここでusersが解放される
};
ケーススタディ
ボタンの設計を考えてみよう
class Button {
public:
    void down(); // ボタン押した
    void up();   // ボタン離した

     bool is_down() const;        // ボタン押されてる?
     bool in_rect(Point p) const; // ある点が範囲内かを判定
};

down(), up()関数ではそれぞれ、ボタンの押下状態によって
表示画像を切替える処理が入っているとする。

ボタンが離されたら確実にup()関数を呼びたい。
どうするか?
ケーススタディ
ボタンを包含する画面クラスはこんな感じになるでしょう。
class View {
    Button ok_button;
public:
    void on_down(Point p)
    {
        if (ok_button.in_rect(p)) // 範囲内なら押す
            ok_button.down();
    }

     void on_up()
     {
         if (ok_button.is_down()) { // 押されていたら離して押下処理
             ok_button.up();
             on_ok_button();
         }
     }

     void on_ok_button() {} // OKボタンが押された
};
ケーススタディ
この設計だと、ボタンが複数あると破綻する。
class View {
    Button ok_button, cancel_button;
public:
    …
    void on_up()
    {
        if (ok_button.is_down()) { // 押されていたら離して押下処理
            ok_button.up();
            on_ok_button();
            return; // 余計な処理はしないで終了
        }
        if (cancel_button.is_down()) {
            cancel_button.up(); // ボタンが離されない可能性がある
            on_cancel_button();
            return;
        }
    }
    …
};
ケーススタディ
離されたら、全てのボタンが確実にup状態になるようにしたい。
Boost.ScopeExitを使おう。
void on_up()
{
    BOOST_SCOPE_EXIT((&)) { // スコープを抜けたら全てのボタンを離す
        ok_button.up();
        cancel_button.up();
    };
    if (ok_button.is_down()) { // 押されていたら離して押下処理
        on_ok_button();
        return; // 全てのボタンが離される
    }
    if (cancel_button.is_down()) {
        on_cancel_button();
        return; // 全てのボタンが離される
    }
} // 全てのボタンが離される

これで、メンバ変数が、特定のメンバ関数の抜けた際に、指定
した処理を確実に行わせることができるようになった。
Boost.ScopeExit
Boost.ScopeExitは、スコープを抜ける際に実行されるブロックを
記述するためのライブラリ。
int value = 0;

void f()
{
    value = 1;

    BOOST_SCOPE_EXIT((&)) { // スコープを抜ける際に実行されるブロック
        value = 3;
    };

    value = 2;
}

f();
assert(value == 3);

Boost.ScopeExitがやっていることは、デストラクタでそのブロック
を実行するクラスとそのオブジェクトを自動生成してるだけ。
Scoped Lockingパターン
Scope Exitの目的特化した例として、Scoped Lockingパターンと
いうのがある。

class Logger {
    Mutex mutex_;
public:
    void write(const std::string& s)
    {
        LockGuard<Mutex> lock(mutex_); // ロックする
        …
    } // スコープ抜けたらロック解除
};

複数ヶ所でロックされる可能性のあるミューテックスを、
それぞれの処理が終わった段階で確実にアンロックする。
まとめ
• RAIIはとても便利だが、メンバ変数をメンバ関数内で自動的
  に解放処理したい場合には、もう一つのRAIIを用意する必要
  がある。

• Boost.ScopeExitはこの手間を減らしてくれる。

• Scoped Locking Patternのように、いろいろな個所で同じことを
  するならScopeExitを直接使うのではなくライブラリ化しよう。

Weitere ähnliche Inhalte

Was ist angesagt?

Goの文法の実例と解説
Goの文法の実例と解説Goの文法の実例と解説
Goの文法の実例と解説Ryuji Iwata
 
Local php-100828 2
Local php-100828 2Local php-100828 2
Local php-100828 2Akio Ishida
 
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーリナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーCODE BLUE
 
WebAPIではじめるphp入門
WebAPIではじめるphp入門WebAPIではじめるphp入門
WebAPIではじめるphp入門Hiroaki Murayama
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
Java並行処理プログラミング 第16章ver2
Java並行処理プログラミング 第16章ver2Java並行処理プログラミング 第16章ver2
Java並行処理プログラミング 第16章ver2Takinami Kei
 
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Yuki Higuchi
 
補足資料 太陽電池モデリング教材
補足資料 太陽電池モデリング教材補足資料 太陽電池モデリング教材
補足資料 太陽電池モデリング教材Tsuyoshi Horigome
 

Was ist angesagt? (8)

Goの文法の実例と解説
Goの文法の実例と解説Goの文法の実例と解説
Goの文法の実例と解説
 
Local php-100828 2
Local php-100828 2Local php-100828 2
Local php-100828 2
 
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーリナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
 
WebAPIではじめるphp入門
WebAPIではじめるphp入門WebAPIではじめるphp入門
WebAPIではじめるphp入門
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
Java並行処理プログラミング 第16章ver2
Java並行処理プログラミング 第16章ver2Java並行処理プログラミング 第16章ver2
Java並行処理プログラミング 第16章ver2
 
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
 
補足資料 太陽電池モデリング教材
補足資料 太陽電池モデリング教材補足資料 太陽電池モデリング教材
補足資料 太陽電池モデリング教材
 

Ähnlich wie Scope Exit

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
Unowned / Weak References with Closure
Unowned / Weak References with ClosureUnowned / Weak References with Closure
Unowned / Weak References with ClosureNaruki Chigira
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & ListenersTaisuke Oe
 
Swift 2.0 で変わったところ「後編」 #cswift
Swift 2.0 で変わったところ「後編」 #cswiftSwift 2.0 で変わったところ「後編」 #cswift
Swift 2.0 で変わったところ「後編」 #cswiftTomohiro Kumagai
 
Boost9 session
Boost9 sessionBoost9 session
Boost9 sessionfreedom404
 
Leap Motion - 1st Review
Leap Motion - 1st ReviewLeap Motion - 1st Review
Leap Motion - 1st ReviewTsukasa Sugiura
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor ExtendedMasamitsu Ishikawa
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Kota Mizushima
 
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Kota Mizushima
 

Ähnlich wie Scope Exit (20)

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
About Jobs
About JobsAbout Jobs
About Jobs
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
Unowned / Weak References with Closure
Unowned / Weak References with ClosureUnowned / Weak References with Closure
Unowned / Weak References with Closure
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & Listeners
 
Swift 2.0 で変わったところ「後編」 #cswift
Swift 2.0 で変わったところ「後編」 #cswiftSwift 2.0 で変わったところ「後編」 #cswift
Swift 2.0 で変わったところ「後編」 #cswift
 
Boost9 session
Boost9 sessionBoost9 session
Boost9 session
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Leap Motion - 1st Review
Leap Motion - 1st ReviewLeap Motion - 1st Review
Leap Motion - 1st Review
 
OSC京都2011
OSC京都2011OSC京都2011
OSC京都2011
 
Flashup 8
Flashup 8Flashup 8
Flashup 8
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor Extended
 
Unityで覚えるC#
Unityで覚えるC#Unityで覚えるC#
Unityで覚えるC#
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
 
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)
 

Mehr von Akira Takahashi (20)

Cpp20 overview language features
Cpp20 overview language featuresCpp20 overview language features
Cpp20 overview language features
 
Cppmix 02
Cppmix 02Cppmix 02
Cppmix 02
 
Cppmix 01
Cppmix 01Cppmix 01
Cppmix 01
 
Modern C++ Learning
Modern C++ LearningModern C++ Learning
Modern C++ Learning
 
cpprefjp documentation
cpprefjp documentationcpprefjp documentation
cpprefjp documentation
 
C++1z draft
C++1z draftC++1z draft
C++1z draft
 
Boost tour 1_61_0 merge
Boost tour 1_61_0 mergeBoost tour 1_61_0 merge
Boost tour 1_61_0 merge
 
Boost tour 1_61_0
Boost tour 1_61_0Boost tour 1_61_0
Boost tour 1_61_0
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
Boost tour 1.60.0 merge
Boost tour 1.60.0 mergeBoost tour 1.60.0 merge
Boost tour 1.60.0 merge
 
Boost tour 1.60.0
Boost tour 1.60.0Boost tour 1.60.0
Boost tour 1.60.0
 
Boost container feature
Boost container featureBoost container feature
Boost container feature
 
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 mergeBoost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
 
Boost Tour 1_58_0
Boost Tour 1_58_0Boost Tour 1_58_0
Boost Tour 1_58_0
 
C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructorC++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
 
C++14 enum hash
C++14 enum hashC++14 enum hash
C++14 enum hash
 
Multi paradigm design
Multi paradigm designMulti paradigm design
Multi paradigm design
 
Start Concurrent
Start ConcurrentStart Concurrent
Start Concurrent
 
Programmer mind
Programmer mindProgrammer mind
Programmer mind
 
Boost.Study 14 Opening
Boost.Study 14 OpeningBoost.Study 14 Opening
Boost.Study 14 Opening
 

Scope Exit