c++ - C++中finally的实现

标签 c++ exception try-catch throw finally

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

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. 对象抛出异常 -> 抛出 -> 异常 -> 对象清理 -> 抛出

最佳答案

标准答案是使用 resource-allocation-is-initialization 的一些变体缩写为 RAII。基本上,您构造一个与 finally 之前 block 内的 block 具有相同作用域的变量,然后在对象析构函数内的 finally block 中执行工作。

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

成为

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

Cleanup cleanupObj;

// Some work.

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

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

或现代 C++

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

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

关于c++ - C++中finally的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/390615/

相关文章:

c# - 嵌套的 try-catch block 有什么意义?

c++ - C/C++ UDP 服务器问题

c++ - HDF5 Cpp - 检索文件中所有组的名称

c# - 在 C# 中处理异常时的良好做法

android - MifareClassic 连接失败 NFC

.net - .Net : try-catch block without any Exception as parameter for catch? 是什么意思

r - tryCatch - 命名空间?

c++ - 应该使用哪个 header 来使用 scoped_ptr

java - System.loadLibrary 适用于 OpenJDK 但不适用于 Oracle

android - 无法展开 RemoteViews android