Sapporocpp#2 exception-primer
Upcoming SlideShare
Loading in...5
×
 

Sapporocpp#2 exception-primer

on

  • 1,641 views

sapporo.cpp #2

sapporo.cpp #2

Statistics

Views

Total Views
1,641
Views on SlideShare
1,631
Embed Views
10

Actions

Likes
0
Downloads
19
Comments
0

3 Embeds 10

http://a0.twimg.com 7
http://twitter.com 2
https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Sapporocpp#2 exception-primer Sapporocpp#2 exception-primer Presentation Transcript

    • 例外安全入門 @hotwatermorning
    • 自己紹介● @hotwatermorning● はてなid:heisesswasser● 大学生● DTMやってます● C++が好きです● 「プログラミングの魔導少女」では 「RangeとPStade.Oven」という記事を書かせ ていただきました。
    • C++erなら
    • 誰しもメモリーリークに
    • 悩まされたことがあるはず
    • 今回のセッションは
    • その悩みを
    • 軽減する
    • 軽減する かもしれない
    • 本日のレシピ1.例外安全とは?2.例外安全性の種類3.例外安全なコードを書くには4.例外安全にするための技法
    • 本日のレシピ1.例外安全とは?2.例外安全性の種類3.例外安全なコードを書くには4.例外安全にするための技法いわゆる、エラーハンドリング/例外ハンドリング関連の内容●は含んでおりません。
    • 本日のレシピ1.例外安全とは?2.例外安全性の種類3.例外安全なコードを書くには4.例外安全にするための技法● いわゆる、エラーハンドリング/例外ハンドリング関連の内容は含んでおりません。● というかそれは僕も知りたいので誰か教えt(ry
    • 1.例外安全とは?
    • 例外安全とは?「あるコード内を実行中の失敗が、メモリリーク、格納データの不整合、不正な出力などの有害な効果を生じないとき、そのコード片は例外安全であると言う。」“例外処理”http://ja.wikipedia.org/wiki/%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86
    • 例外安全とは?「例外安全なプログラミングとは、 例外を投げる可能性があるコードが実際に例外を投げた場合に、 プログラムの状態が壊れずリソースもリークしないように作るプログラミングのことを言います。 」“例外安全なプログラミング”http://www.kmonos.net/alang/d/2.0/exception-safe.html
    • 例外安全とは?● 例外が発生しても適切に対処できるよう なコードを書く。● 適切に対処しないと・・・ ‣ メモリリーク、リソースリーク ‣ 中途半端な操作の完了 ‣ デストラクタから例外が投げられる と・・・
    • 例外安全でないコードの例(1)void SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; read_data(data_, n);}
    • 例外安全でないコードの例(1)void SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; //←ここや read_data(data_, n);}
    • 例外安全でないコードの例(1)void SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; //←ここや read_data(data_, n);//←ここで}
    • 例外安全でないコードの例(1)void SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; //←ここや read_data(data_, n);//←ここで} //例外が投げられると...??
    • 例外安全でないコードの例(1)void SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; //←ここや read_data(data_, n);//←ここで} //例外が投げられると...??SampleClassの状態が壊れてしまう!!
    • 例外安全でないコードの例(2)SampleClass2 & SampleClass2::operator= (SampleClass2 const &rhs){ data1_ = rhs.data1_; data2_ = rhs.data2_; data3_ = rhs.data3_; data4_ = rhs.data4_; return *this;}
    • 例外安全でないコードの例(2)SampleClass2 & SampleClass2::operator= (SampleClass2 const &rhs){ data1_ = rhs.data1_; data2_ = rhs.data2_;//このうち data3_ = rhs.data3_; data4_ = rhs.data4_; return *this;}
    • 例外安全でないコードの例(2)SampleClass2 & SampleClass2::operator= (SampleClass2 const &rhs){ data1_ = rhs.data1_; data2_ = rhs.data2_;//このうち data3_ = rhs.data3_;//どれかで data4_ = rhs.data4_; return *this;}
    • 例外安全でないコードの例(2)SampleClass2 & SampleClass2::operator= (SampleClass2 const &rhs){ data1_ = rhs.data1_; data2_ = rhs.data2_;//このうち data3_ = rhs.data3_;//どれかで data4_ = rhs.data4_;//例外が起きたら return *this;}
    • 例外安全でないコードの例(2)SampleClass2 & SampleClass2::operator= (SampleClass2 const &rhs){ data1_ = rhs.data1_;//これはどうなる? data2_ = rhs.data2_;//このうち data3_ = rhs.data3_;//どれかで data4_ = rhs.data4_;//例外が起きたら return *this;}
    • 例外安全なコードじゃないと
    • 例外が起きたときにきちんと対処できない
    • よし、
    • 例外安全なコードを書こう!
    • と、そのまえに
    • 2.例外安全性の種類
    • 例外安全性の種類● 例外を投げない保証 高● 強い例外安全 例外安全性● 基本的な例外安全● 例外安全保証なし 低
    • 例外安全性の種類● 例外を投げない保証● 強い例外安全 但し・・・● 基本的な例外安全● 例外安全保証なし
    • 例外安全性の種類● 例外を投げない保証 高● 強い例外安全 コスト…● 基本的な例外安全● 例外安全保証なし 低
    • 例外安全性の種類● 例外安全保証なし
    • 例外安全性の種類 ● 例外安全保証なし● その関数や呼び出し先で例外が起きると リソースがリークしてしまうかもしれな い・・・
    • 例外安全性の種類 ● 例外安全保証なしvoid SampleClass::ReadData(int n){ delete [] data_; data_ = new T[n]; read_data(data_, n);}
    • 例外安全性の種類● 基本的な例外安全の保証
    • 例外安全性の種類 ● 基本的な例外安全の保証● 例外が投げられても、いかなるリソース もリークしない。
    • 例外安全性の種類 ● 基本的な例外安全の保証● 例外が投げられても、いかなるリソース もリークしない。● 副作用は出るかもしれない(データの変 更や出力など。)
    • 例外安全性の種類 ● 基本的な例外安全の保証● 例外が投げられても、いかなるリソース もリークしない。● コンテナの中で例外が発生した場合、一 貫性は保っているが、予測可能な状態と は限らない。● なのでその後、削除や再利用はできる。
    • 例外安全性の種類 ● 基本的な例外安全の保証void SampleClass::ReadData(int n){ delete [] data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); } catch(...) { delete [] data_; data_ = 0; }}
    • 例外安全性の種類● 強い例外安全の保証
    • 例外安全性の種類 ● 強い例外安全の保証● 例外が起きたなら、全ての変更は ロールバックされる● 完全な成功か、例外による完全な失 敗かの2つの状況になる
    • 例外安全性の種類 ● 強い例外安全の保証void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全性の種類● 例外を投げない保証(no throw)
    • 例外安全性の種類 ● 例外を投げない保証(no throw)● 操作は全て正しく完了されることが 保証される。
    • 例外安全性の種類 ● 例外を投げない保証(no throw)● 操作は全て正しく完了されることが 保証される。● 例)基本データ型の代入などは例外 が起きない
    • 例外安全性の種類 ● 例外を投げない保証(no throw)● 操作は全て正しく完了されることが 保証される。● 例)基本データ型の代入などは例外 が起きない● 呼び出し先も例外を投げない保証が できなければならない
    • 例外安全性の種類● 例外を投げない保証(no throw)void foo(){ int n1 = 0x10; int n2 = n1; int *pn1 = &n1; int *pn2 = pn1;}
    • 3.例外安全なコードを書くには
    • 例外安全なコードを書くには● ある実行パス中の例外安全性は、その工 程で一番低いものになる。
    • 例外安全なコードを書くには● ある実行パス中の例外安全性は、その工 程で一番低いものになる。● どゆこと?
    • 例外安全なコードを書くにはint baz() { return bar() * bar(); }void foo(){ int n1 = 1; //例外安全なコード int n2 = bar(); //例外安全でないコード int n3 = 3; //例外安全なコード int n4 = baz(); //例外安全でないコード}
    • 例外安全なコードを書くには(さっきの「強い例外安全」のサンプルコード)void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全なコードを書くには(さっきの「強い例外安全」のサンプルコード)void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); //←もしこの関数が delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全なコードを書くには(さっきの「強い例外安全」のサンプルコード)void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); //←もしこの関数が delete [] tmp; //例外安全じゃないと } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全なコードを書くには(さっきの「強い例外安全」のサンプルコード)void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); //←もしこの関数が delete [] tmp; //例外安全じゃないと } catch(...) { //ReadData関数は delete [] data_; d...//完全な例外安全とは } //言えなくなる}
    • 例外安全なコードを書くには● ある実行パス中の例外安全性は、その工 程で一番低いものになる。● 呼び出し先の例外安全性にも左右されて しまう。
    • 例外安全なコードを書くには● ある実行パス中の例外安全性は、その工 程で一番低いものになる。● 呼び出し先の例外安全性にも左右されて しまう。● プログラムの中で基本的な機能であるほ ど、しっかりした例外安全性を実装して いなければならない。(コンテナなど)
    • 例外安全なコードを書くには● ある実行パス中の例外安全性は、その工 程で一番低いものになる。● 呼び出し先の例外安全性にも左右されて しまう。● プログラムの中で基本的な機能であるほ ど、しっかりした例外安全性を実装して いなければならない。(コンテナなど)● 標準のコンテナは大体強い保証を満たす
    • 例外安全なコードを書くには● それぞれの関数で例外を投げうる部分と 投げない部分を明確に分離する。● 本来の処理の成功を確認した時点で、例 外を投げない部分を使って、状態の変更 と後処理を行うようにする。
    • 例外安全なコードを書くには● 例外中立について
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; } //例外安全に書けましたね!}
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; } //でもいざ例外が起きたときに}
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; } //ReadDataの呼び出し元は} //ここで起きた例外をなにも知らない
    • 例外安全なコードを書くには● 例外中立について● コンテナなどで例外が起きると、その例 外が起きるまでのコンテキストを知って いるのは呼び出し元だけ。
    • 例外安全なコードを書くには● 例外中立について● コンテナなどで例外が起きると、その例 外が起きるまでのコンテキストを知って いるのは呼び出し元だけ。● コンテナでは、自分の行った範囲の例外 は安全に処理できるけど、他は無理。
    • 例外安全なコードを書くには● 例外中立について● コンテナなどで例外が起きると、その例 外が起きるまでのコンテキストを知って いるのは呼び出し元だけ。● コンテナでは、自分の行った範囲の例外 は安全に処理できるけど、他は無理。● 適切に処理できるところまでは例外を正 しく伝える。
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全なコードを書くにはvoid SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; //正しくはこう。 }}
    • 例外安全なコードを書くには● 単一の関数にatomicでない複数の処理が あると、例外安全の強い保証をするのは 不可能。● 例)std::coutに出力してからstd::cerr に出力
    • 4.例外安全にするための技法
    • これまでのことは
    • いまから紹介する2つのテクニックの
    • 布石に過ぎなかった
    • 布石に過ぎなかった \ばばーん/
    • 例外安全にするための技法● いままで説明してきたことを上手く実装 するためのテクニック
    • 例外安全にするための技法● いままで説明してきたことを上手く実装 するためのテクニック● Swap
    • 例外安全にするための技法● いままで説明してきたことを上手く実装 するためのテクニック● Swap● RAII(Resource Acquisition Is Initialization)
    • 例外安全にするための技法 ● Swap● 実体を他に作って、全て成功した ら、変更したいリソースとSwapする
    • 例外安全にするための技法 ● Swap● 実体を他に作って、全て成功した ら、変更したいリソースとSwapする● Swapは、例外を投げない保証を必ず 守る
    • 例外安全にするための技法template<typename T>void swap(T &lhs, T &rhs){ T tmp = lhs; lhs = rhs; rhs = tmp;}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //頑張って強い例外安全にしてるけど}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //ロールバック用にいろいろ書いてて}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //例外を投げる部分が}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //例外を投げない部分に囲まれて}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //Try-Catchも入り乱れて}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //ちょっと複雑・・・}
    • 例外安全なコードを書くには● それぞれの関数で例外を投げうる部分と 投げない部分を明確に分離する。● 本来の処理の成功を確認した時点で、例 外を投げない部分を使って、状態の変更 と後処理を行うようにする。
    • 例外安全にするための技法 ● Swap● 実体を他に作って、全て成功した ら、変更したいリソースとSwap
    • 例外安全にするための技法 ● Swap● 実体を他に作って、全て成功した ら、変更したいリソースとSwap例外を投げうる部分 投げない部分
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = new T[n]; //先に確保 try { read_data(tmp, n);//そいつで処理 } catch(...) { delete [] tmp; } std::swap(data_, tmp);//終わったら入れ替え delete [] tmp; //後処理}
    • 例外安全にするための技法 ● Swap● 例外を投げうる部分と投げない部分を明 確に分離● 例外を投げる部分が成功したら例外を投 げない部分で状態を変更● ロールバック用のTry-Catchは要らなく なる!
    • 例外安全にするための技法 ● Swap● 例外を投げうる部分と投げない部分を明 確に分離● 例外を投げる部分が成功したら例外を投 げない部分で状態を変更● ロールバック用のTry-Catchは要らなく なる! (リソース管理用のは必要・・・)
    • 例外安全にするための技法 ● Swap● 自作クラスでも、 Copy-Constructableなクラスなら swapを実装する。
    • 例外安全にするための技法void SampleClass::swap(SampleClass &rhs){ //標準のswap関数や std::swap(data_, rhs.data_); //それ用のswap関数などで other_data_.swap(rhs.other_data_);}
    • 例外安全にするための技法 ● Swap● 自作クラスでも、 Copy-Constructableなクラスなら swapを実装する。● SampleClass (SampleClass const &rhs);
    • 例外安全にするための技法 ● Swap● 自作クラスでも、 Copy-Constructableなクラスなら swapを実装する。● 実装すると・・・
    • 例外安全にするための技法 ● Swap● 自作クラスでも、 Copy-Constructableなクラスなら swapを実装する。● Assignableなクラスに出来る。● SampleClass & operator=(SampleClass const &)
    • 例外安全にするための技法SampleClass & SampleClass::operator= (SampleClass const &rhs){ //コピーコンストラクタ SampleClass tmp(rhs); //swap tmp.swap(*this); return *this;}
    • 例外安全にするための技法SampleClass & SampleClass::operator= (SampleClass const &rhs){ //コピーコンストラクタ SampleClass tmp(rhs); //swap tmp.swap(*this); さらにまとめて return *this; 書くと}
    • 例外安全にするための技法SampleClass & SampleClass::operator= (SampleClass const &rhs){ SampleClass(rhs).swap(*this); return *this;}
    • 例外安全にするための技法SampleClass & SampleClass::operator= (SampleClass const &rhs){ SampleClass(rhs).swap(*this); return *this;} メンバ変数がAssignableであることを 要求しない
    • 例外安全にするための技法SampleClass & SampleClass::operator= (SampleClass const &rhs){ SampleClass(rhs).swap(*this); return *this;} Copy And Swap
    • 例外安全にするための技法 ● RAII● 「リソースの確保は初期化である」
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //リソース管理のためにコードが複雑に}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //deleteも分散してしまった}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; } //対応していない}
    • 例外安全にするための技法 ● RAII● 「リソースの確保は初期化である」● コンストラクタでリソースを確保● デストラクタでリソースを破棄
    • 例外安全にするための技法 ● RAII● 「リソースの確保は初期化である」● コンストラクタでリソースを確保● デストラクタでリソースを破棄 対応!!
    • 例外安全にするための技法 ● RAIIclass RAIIClass{ RAIIClass(Resource r) : r_(r) {} RAIIClass(Args as) : r_(CreateResource(as)) {} ~RAIIClass() { DisposeResource(r_); }private: Resource r_;};
    • 例外安全にするための技法 ● RAII● これをメモリ管理に使ったのがいわ ゆるスマートポインタ
    • 例外安全にするための技法 ● RAII● これをメモリ管理に使ったのがいわ ゆるスマートポインタ● プログラマはリソース解放のめんど くささから解放される!
    • 例外安全にするための技法 ● RAII● これをメモリ管理に使ったのがいわ ゆるスマートポインタ● プログラマはリソース解放のめんど くささから解放される!● 例外安全とか考えなくても使うべ き!
    • 例外安全にするための技法 ● RAII● これがどのように例外安全性の点で 重宝されるのか?
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; }}
    • 例外安全にするための技法 ● RAII● Deleteのために例外をCatchしなく ちゃいけなかった
    • 例外安全にするための技法 ● RAII● Deleteのために例外をCatchしなく ちゃいけなかった● でもRAIIなクラスを使うと、Delete は自動化できる
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; これが read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; throw; }}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ shared_array<T> tmp = data_; try { data_.reset(new T[n]); こうなる read_data(data_, n); } catch (...) { data_ = tmp; }}
    • 例外安全にするための技法 ● RAII● どこで起きるかわからないような例 外によって関数を抜けるときも、そ の時に自動でリソースが解放され る!● リソース解放のためのTry-Catchは要 らなくなる!
    • 例外安全にするための技法 ● RAII● どこで起きるかわからないような例 外によって関数を抜けるときも、そ の時に自動でリソースが解放され る!● リソース解放のためのTry-Catchは要 らなくなる!(強い例外安全保証の ためのは必要・・・)
    • 例外安全にするための技法 ● SwapとRAII
    • 例外安全にするための技法 ● SwapとRAII1.Swapはロールバック用のTry- Catchを不要にする。
    • 例外安全にするための技法 ● SwapとRAII1.Swapはロールバック用のTry- Catchを不要にする。2.RAIIはリソース管理用のTry- Catchを不要にする。
    • 例外安全にするための技法 ● SwapとRAII1.Swapはロールバック用のTry- Catchを不要にする。2.RAIIはリソース管理用のTry- Catchを不要にする。3.例外中立のために、例外が起き てもいじらないで伝える。
    • 例外安全にするための技法 ● SwapとRAII 合体
    • 例外安全にするための技法void SampleClass::ReadData(int n){ shared_array<T> tmp(new T[n]); read_data(tmp_, n); std::swap(data_, tmp);}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ shared_array<T> tmp(new T[n]); read_data(tmp_, n); std::swap(data_, tmp);} おわかりいただけただろうか
    • 例外安全にするための技法void SampleClass::ReadData(int n){ shared_array<T> tmp(new T[n]); read_data(tmp_, n); std::swap(data_, tmp);} おわかりいただけただろうか ではもう一度・・・
    • 例外安全にするための技法void SampleClass::ReadData(int n){ T *tmp = data_; data_ = 0; try { data_ = new T[n]; read_data(data_, n); delete [] tmp; } catch(...) { delete [] data_; data_ = tmp; }}
    • 例外安全にするための技法void SampleClass::ReadData(int n){ shared_array<T> tmp(new T[n]); read_data(tmp_, n); std::swap(data_, tmp);}
    • 例外安全にするための技法 ● SwapとRAII● 適切なコードを書けば、例外安全 性のためにTry-Catchを書く必要 はない。
    • 例外安全にするための技法 ● デストラクタで例外
    • 例外安全にするための技法 ● デストラクタで例外● 禁止!
    • 例外安全にするための技法 ● デストラクタで例外● 禁止!● 配列を安全にできない● 例外が起きたときにスタックの巻 き戻しを安全にできない● 全ての例外安全の努力が水の泡!
    • 5.まとめ
    • まとめ● 例外安全なコードを書くには
    • まとめ● 例外安全なコードを書くには● 例外を投げる部分と投げない部分を 分離して、例外のある処理の成功を 確認してから、状態を変更する。● RAIIを使用してリソースの管理を自 動化する
    • まとめ● 今回の内容はほとんど全て 「Exceptional C++」 (ハーブ・サッター著) に書かれています● あと「C++ Coding Standard」も
    • おしまい。