在 C 中实现 finally

新手上路,请多包涵

这是在标准 C++ 中实现类似最终行为的好方法吗? (无特殊指针)

 class Exception : public Exception
    { public: virtual bool isException() { return true; } };

class NoException : public Exception
    { public: bool isException() { return false; } };

Object *myObject = 0;

try
{
  // OBJECT CREATION AND PROCESSING
  try
  {
    myObject = new Object();

    // Do something with myObject.
  }

  // EXCEPTION HANDLING
  catch (Exception &e)
  {
    // When there is an excepion, handle or throw,
    // else NoException will be thrown.
  }

  throw NoException();
}

// CLEAN UP
catch (Exception &e)
{
  delete myObject;

  if (e.isException()) throw e;
}

  1. 对象没有抛出异常 -> NoException -> 对象已清理
  2. 对象抛出的异常 -> 已处理 -> NoException -> 对象已清理
  3. 对象抛出的异常 -> 抛出 -> 异常 -> 对象清理 -> 抛出

原文由 Tamara Wijsman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 426
1 个回答

标准答案是使用 资源分配即初始化 缩写 RAII 的一些变体。基本上,您构造一个变量,该变量与finally之前块内的块具有相同的范围,然后在对象析构函数内的finally块中执行工作。

 try {
   // Some work
}
finally {
   // Cleanup code
}

变成

class Cleanup
{
public:
    ~Cleanup()
    {
        // Cleanup code
    }
}

Cleanup cleanupObj;

// Some work.

这看起来非常不方便,但通常有一个预先存在的对象会为您进行清理。在您的情况下,您似乎想要破坏 finally 块中的对象,这意味着智能或唯一指针将执行您想要的操作:

 std::unique_ptr<Object> obj(new Object());

或现代 C++

 auto obj = std::make_unique<Object>();

无论抛出哪个异常,对象都会被破坏。回到 RAII,在这种情况下,资源分配是为 Object 分配内存并构造它,初始化是 unique_ptr 的初始化。

原文由 David Norman 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题