お知らせ

電子会議

ライブラリ

FDelphi サイト全文検索

Delphi FAQ一覧

サンプル蔵



FDelphi FAQ
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」

[Q]
 例外オブジェクトとか,構造化例外ということばの意味がわかり ません.保護ブロックと言うのもよくわかりません.

[A]
 手続きの中で「例外オブジェクト」という特殊なオブジェクト
を生成すると,その手続きはそこで強制的に中断されて,その手続き
の呼出元にリターンしてしまいます.その戻りかたは特殊な状態
になっていて,呼出もとの手続きから,それを呼び出した呼出もと
へとどんどんとさかのぼって,ついには「デフォルトの例外ハンドラ」
というところまで,強制的な中断状態のまま制御が戻って行くことに
なっています.

procedure Proc;
begin
  Proc0;
  MessageBeep(0);
end;

  procedure Proc0;
  begin
    Proc00;
    MessageBeep(0);
  end;

    procedure Proc00;
    begin
      Proc000;
      MessageBeep(0);
    end;

      { 例外が起きる手続き }
      procedure Proc000;
      begin
        raise Exception.Create('例外だよーん');
      end;

というコードを作って,Proc 手続きを実行すると一番深くネストした
Proc000で例外が起きて,MessageBeep は一度も実行されることなく
「! 例外だよーん」というメッセージボックスが表示されます.

 これは実は非常に便利でして,やってはいけないことが起きたときに
処理を中断して後の処理をスキップするということを自動でやって
くれるので,例えばゼロで除算しないかどうかを事前に判断して
処理を分岐するなどというコードを記述しないでも良いという利点
があります.

 さて,Helpの「リソース保護ブロックの作成」によれば,イベント
ハンドラや手続きの中で TStringList などのオブジェクトやメモリを
動的に確保して使うときには,try..finally..end で囲って必ず
リソースの解放を行う必要がある,となっています.
 リソースの割り当てとは
・動的なメモリの獲得:AllocMem,GetMem などで取ってくる
・動的にオブジェクトを生成する:生成の過程でメモリの獲得がされる
などを言います.

 例外が起きてしまうと,起きたところより後ろのコードは一切
実行されずに,一気にデフォルト例外ハンドラというところまで
戻っていってしまうので,メモリの解放とかオブジェクトの廃棄
などを記述したコードに制御がわたらない可能性があります.
 そこで,finally 部にリソースの解放を行うコードを書き込んで
おけば,例外がもし起きても,すぐには戻っていかないで,そこだけ
は必ず実行してから制御が戻っていきます.そのため,例外が起きそう
な危ないことを,あらかじめ安全かどうかを判断せずに実行しちゃって
もメモリリークの心配は無くなる,という訳なのでした.
[例]




ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。

Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会