0

サブリソースを使用するリソースの開閉機構を作成する場合、エラー時のサブリソースの解放を処理するための 2 つのパターンがあります。

1

RESULT Open() {
   RESULT result;
   result = OpenSubResourceA();
   if (result == SUCCESS)
      result = OpenSubResourceB();

   /* Do not handle error case, the convention is that the caller 
    * will call Close whatever the return code of Open is */
   return result;
}

2

RESULT Open() {
   RESULT result;
   result = OpenSubResourceA();
   if (result == SUCCESS)
      result = OpenSubResourceB();

   if (result != SUCCESS)
      ReleaseSubResourceA();

   /* Release A if opening B failed since the convention is 
    * that the caller calls Close only if Open succeeds */

   return result;
}

もちろん、2 つ以上のサブリソースで一般化できます。

好きなやり方は何ですか?なぜ ?

編集

ご意見ありがとうございます。メイン リソースが Open/Close 呼び出し以外の中間状態であってはならないという考えは、#2 が実際に最善の解決策であると確信させました。

4

4 に答える 4

2

これは、C ではきれいに実行できないことの 1 つです。

私がしているのはこのパターンです(非常に一般的です):

   aquire_1;
   if (fail) goto fail_1;

   aquire_2;
   if (fail) goto fail_2;

fail_2:
    release_1;
fail_1:
    return err;
于 2012-08-13T12:58:05.107 に答える
1

操作が失敗した場合、リソースは呼び出し前と同じ状態にある必要があるため、クライアントはそれを引き続き使用できます。何らかの操作が失敗した場合、リソースを不確定なハーフレディ状態のままにしておくことは悪い習慣です。不確定な状態からクリーンアップして回復できない (したくない) 場合は、リソースを明示的にエラー状態にする必要がありますisError()true

それは#2です

于 2012-08-13T13:02:58.200 に答える
1

原則として、メモリやファイル ハンドルなどのリソースを割り当てる関数がある場合、open メソッドが失敗した場合、未割り当てのリソースは存在しないはずです。オープンに失敗すると、プログラムは at でオープン呼び出しが発生しなかった場合と同じ状態に戻ります。

そのため、open 関数で未使用のリソースを閉じます。可能であれば、リソースを割り当てた場所の近くで解放する方がよいと思います。コードが読みやすくなります。

于 2012-08-13T13:02:19.510 に答える
0

他の人が言ったことに加えて、Open() の呼び出し元は、サブリソースの存在さえ知らない可能性があります (リソースの性質によって異なります)。その場合、呼び出し元はきれいに整理することができず、Open 関数がそれを自分で行う必要があります。

于 2012-08-13T14:22:36.313 に答える