* メモ [#aa6c98da] #contents ** ver2.0用の情報だったり古い情報だったり [#t3183086] *** インスタンスの生成手順 [#e0c3e509] - メモリ領域は確保済みとする。 - 1) .initデータを領域にコピー。 - 2) コンストラクタがあれば実行。 - 3) invariantがあれば実行。 - 4) scopeなclassもしくはstructなオブジェクトならデストラクタスタックに自身を追加 *** 関数に入るときの手順 [#v722abbb] - 1) 関数スタックにプッシュ *** 関数から抜けるときの手順 [#saac6cfb] - 1) 関数スタックの情報を元に,デストラクタスタックに積まれているオブジェクトを必要なだけポップ&実行 - 2) 関数スタックからポップ *** メンバ関数に入るときの手順 [#e65b2f19] - 1) publicなメンバ関数の呼び出しならinvariantがあれば実行。 - 2) 『関数に入るときの手順』を実行 *** メンバ関数から抜けるときの手順 [#yf66bb06] - 1) 『関数から抜けるときの手順』を実行 - 2) publicな関数の呼び出しならinvariantがあれば実行。 *** コンストラクタの手順 [#e7a580bf] - 1) 『関数に入るときの手順』を実行 - 2) structメンバ変数をデストラクタスタックにプッシュ - 3) 関数本体を実行 - 4) invariantがあれば実行 - 5) コンストラクトが正常に終了したと判断したので,デストラクタスタックに追加済みのstructメンバ変数をポップ。 - 6) 『関数から抜けるときの手順』を実行 *** デストラクタの手順 [#m98537bc] - 1) 『関数に入るときの手順』を実行 - 2) invariantがあれば実行 - 3) 関数本体を実行 - 4) 『関数から抜けるときの手順』を実行 *** tryキーワードの手順 [#yf2daf24] - 1) catchポイントを関数スタックにプッシュ *** catchキーワードの手順 [#q55cec00] - 1) catchポイントを関数スタックからポップ - 2) 必要な数だけデストラクタスタックをポップ&実行 *** finalyキーワードの手順 [#ne5b51a9] - 1) catchポイントを関数スタックからポップ *** throwキーワードの手順 [#r72394de] - 1) throwされたStd.IExceptionをひかえておく - 2) 関数スタックをなめていき,該当するcatchポイントを探す。見つからなければContext停止。 - 3) 該当のcatchポイントまで関数スタックをポップ&デストラクタスタックのポップ&実行を繰り返す。 - このとき,デストラクタ実行中に新しい例外がthrowされたら再び1に戻り,古いStd.IExceptionは上書きされる。(C#の挙動にあわせた) ** メモ [#k2ac7658] *** 例外発生時のデストラクトでさらに例外が発生したとき [#n30c1192] C#の挙動にあわせよう。 #code(csharp,){{ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CSharpTest { class Program { class ExceptionA : Exception { public ExceptionA( string msg ) : base( "ExceptionA:" + msg) { } }; class ExceptionB : Exception { public ExceptionB( string msg ) : base( "ExceptionB:" + msg) { } }; class Hoge : IDisposable { string str; public Hoge(string aStr) { str = aStr; } public void Dispose() { System.Console.WriteLine(str + " Hoge Dispose Enter"); throw new ExceptionA(str + " hoge dispose exp"); System.Console.WriteLine(str + " Hoge Dispose Exit"); } }; static void Main(string[] args) { try { using (var hogeA = new Hoge("a")) { using (var hogeB = new Hoge("b")) { System.Console.WriteLine("Enter Scope"); throw new ExceptionB("throw exp"); System.Console.WriteLine("Exit Scope"); } } } catch (ExceptionA exp) { System.Console.WriteLine("Catch A"); } catch (ExceptionB exp) { System.Console.WriteLine("Catch B"); } finally { } } } } }} 実行結果 #code(){{ Enter Scope b Hoge Dispose Enter a Hoge Dispose Enter Catch A 続行するには何かキーを押してください . . . }} ってことで最後に投げられた例外が有効になるみたい。 |