C++ 如何在不尝试 {} finally{} 的情况下安全地关闭文件?

mab*_*abg 2 c++ try-catch try-finally

假设有这样一个类:

class A {
private:
   QFile file;

public:
   A::A(QFile file): file(file) {}

   void doSomething() {
      file.open(QIODevice::WriteOnly); 
      // ... do operations that can throw an exception
      file.close();
   } 
}
Run Code Online (Sandbox Code Playgroud)

如果发生某些事情, close() 永远不会调用它。正确的方法是使用 try - finally,但 C++ 不支持它:

class A {
private:
   QFile file;

public:
   A::A(QFile file): file(file) {}

   void doSomething() {
      file.open(QIODevice::WriteOnly); 
      try {
          // ... do operations that can throw an exception
      }
      finally {
          file.close();
      }
   } 
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在C++上做到这一点?

Jam*_*nze 5

通常的解决方案是使用 RAII:在这种情况下,例如,如果 QFile有一个“正确”的析构函数,只需将其声明为局部变量就可以解决问题:

void A::doSomething()
{
    QFile file;
    file.open(...);
    //  ...
    file.close();   //  So you can check that everything when right.
}
Run Code Online (Sandbox Code Playgroud)

文件QFile被破坏时应该自动关闭,但如果之前没有关闭,您将无法检查状态(并且文件中的数据可能不完整)。

如果由于某种原因这不可行,您可能需要使用作用域包装类:

class QFileWrapper
{
    QFile* myFile;
public:
    QFileWrapper( QFile* file ) : myFile( file ) {}
    ~QFileWrapper() { myFile->close(); }
};
Run Code Online (Sandbox Code Playgroud)

std::ofstream实际上,我用一个函数为 做了很多这样的commit 事情,它是构造函数,它获取文件名并进行打开。该commit函数关闭文件,如果关闭成功,则设置一个文件已提交的标志。析构函数测试该标志,如果文件尚未提交,它将关闭它删除它,以便不会留下任何部分文件。