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 中干净地完成。

我做的是这种模式(很常见):

   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

通常,如果我有一个分配资源的函数 - 内存或文件句柄或任何东西 - 如果 open 方法失败,则应该没有未分配的资源。失败的打开应该将程序返回到与在 at 未发生打开调用时相同的状态。

所以,我会在 open 函数中关闭未使用的资源。我认为最好在尽可能靠近分配它们的位置释放资源。它使代码更具可读性。

于 2012-08-13T13:02:19.510 回答
1

如果操作失败,资源应该与调用之前的状态相同,以便客户端可以继续使用它。如果某些操作失败,让资源处于不确定的半就绪状态是不好的做法。如果你不能(不想)清理并从不确定状态恢复,那么资源应该显式呈现为错误状态,例如一些成员isError()应该开始返回true

那是#2

于 2012-08-13T13:02:58.200 回答
0

除了其他人所说的之外, Open() 的调用者甚至可能不知道子资源的存在(取决于资源的性质)。在这种情况下,调用者无法彻底清理干净,Open 函数必须自己完成。

于 2012-08-13T14:22:36.313 回答