Your SlideShare is downloading. ×
0
メンバ変数のメンバ関数内での    リソース管理        高橋晶(Akira Takahashi)            id:faith_and_brave                    @cpp_akira        Bo...
RAII• C++には、RAII(Resource Acquisition Is Initialization:リソース  確保は初期化である)というイディオムがある。• 簡単に言えば、確保したリソースはデストラクタで自動的に  解放する、とい...
メンバ変数のリソース管理• メンバ変数の寿命がクラスと同じでよければ、RAIIが有用。class X {    std::vector<User> users;public:    ~X()    {    } // ここでusersが解放され...
ケーススタディボタンの設計を考えてみようclass Button {public:    void down(); // ボタン押した    void up();   // ボタン離した     bool is_down() const;   ...
ケーススタディボタンを包含する画面クラスはこんな感じになるでしょう。class View {    Button ok_button;public:    void on_down(Point p)    {        if (ok_but...
ケーススタディこの設計だと、ボタンが複数あると破綻する。class View {    Button ok_button, cancel_button;public:    …    void on_up()    {        if (o...
ケーススタディ離されたら、全てのボタンが確実にup状態になるようにしたい。Boost.ScopeExitを使おう。void on_up(){    BOOST_SCOPE_EXIT((&)) { // スコープを抜けたら全てのボタンを離す   ...
Boost.ScopeExitBoost.ScopeExitは、スコープを抜ける際に実行されるブロックを記述するためのライブラリ。int value = 0;void f(){    value = 1;    BOOST_SCOPE_EXIT...
Scoped LockingパターンScope Exitの目的特化した例として、Scoped Lockingパターンというのがある。class Logger {    Mutex mutex_;public:    void write(con...
まとめ• RAIIはとても便利だが、メンバ変数をメンバ関数内で自動的  に解放処理したい場合には、もう一つのRAIIを用意する必要  がある。• Boost.ScopeExitはこの手間を減らしてくれる。• Scoped Locking Pat...
Upcoming SlideShare
Loading in...5
×

Scope Exit

5,775

Published on

0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,775
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
20
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Scope Exit"

  1. 1. メンバ変数のメンバ関数内での リソース管理 高橋晶(Akira Takahashi) id:faith_and_brave @cpp_akira Boost.勉強会 #8 大阪 2012/02/11(土)
  2. 2. RAII• C++には、RAII(Resource Acquisition Is Initialization:リソース 確保は初期化である)というイディオムがある。• 簡単に言えば、確保したリソースはデストラクタで自動的に 解放する、というもの。void f(){ File file; file.open("a.txt"); if (!file.write("xxxxxxxx")) { return; // 途中で抜けてもファイルは閉じられる }} // ファイルが閉じられる• これはローカル変数には非常に有効。
  3. 3. メンバ変数のリソース管理• メンバ変数の寿命がクラスと同じでよければ、RAIIが有用。class X { std::vector<User> users;public: ~X() { } // ここでusersが解放される};
  4. 4. ケーススタディボタンの設計を考えてみようclass Button {public: void down(); // ボタン押した void up(); // ボタン離した bool is_down() const; // ボタン押されてる? bool in_rect(Point p) const; // ある点が範囲内かを判定};down(), up()関数ではそれぞれ、ボタンの押下状態によって表示画像を切替える処理が入っているとする。ボタンが離されたら確実にup()関数を呼びたい。どうするか?
  5. 5. ケーススタディボタンを包含する画面クラスはこんな感じになるでしょう。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ボタンが押された};
  6. 6. ケーススタディこの設計だと、ボタンが複数あると破綻する。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; } } …};
  7. 7. ケーススタディ離されたら、全てのボタンが確実に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; // 全てのボタンが離される }} // 全てのボタンが離されるこれで、メンバ変数が、特定のメンバ関数の抜けた際に、指定した処理を確実に行わせることができるようになった。
  8. 8. Boost.ScopeExitBoost.ScopeExitは、スコープを抜ける際に実行されるブロックを記述するためのライブラリ。int value = 0;void f(){ value = 1; BOOST_SCOPE_EXIT((&)) { // スコープを抜ける際に実行されるブロック value = 3; }; value = 2;}f();assert(value == 3);Boost.ScopeExitがやっていることは、デストラクタでそのブロックを実行するクラスとそのオブジェクトを自動生成してるだけ。
  9. 9. Scoped LockingパターンScope Exitの目的特化した例として、Scoped Lockingパターンというのがある。class Logger { Mutex mutex_;public: void write(const std::string& s) { LockGuard<Mutex> lock(mutex_); // ロックする … } // スコープ抜けたらロック解除};複数ヶ所でロックされる可能性のあるミューテックスを、それぞれの処理が終わった段階で確実にアンロックする。
  10. 10. まとめ• RAIIはとても便利だが、メンバ変数をメンバ関数内で自動的 に解放処理したい場合には、もう一つのRAIIを用意する必要 がある。• Boost.ScopeExitはこの手間を減らしてくれる。• Scoped Locking Patternのように、いろいろな個所で同じことを するならScopeExitを直接使うのではなくライブラリ化しよう。
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×