1

假设这样一个类:

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();
   } 
}

如果发生某些事情,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();
      }
   } 
}

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

4

2 回答 2

4

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

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

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

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

class QFileWrapper
{
    QFile* myFile;
public:
    QFileWrapper( QFile* file ) : myFile( file ) {}
    ~QFileWrapper() { myFile->close(); }
};

实际上std::ofstream,我用一个commit 函数为 . 该commit函数关闭文件,如果关闭成功,则设置文件已提交的标志。析构函数测试这个标志,如果文件没有被提交,它会关闭它删除它,这样就不会留下任何部分文件。

于 2014-04-09T14:15:15.277 回答
0

以下代码大致相似:

try {    
    /*do something that may throw an exception*/    
} catch (.../*the ellipsis means catch anything*/){   
    /* any cleanup */
    throw; /*this rethrows the exception, not compulsory to include*/
}

这并不完全相同,因为只有在抛出异常时才会输入 catch 块(与finallyJava 中的块不同)。

但是C++不需要构造finally,因为 C++ 对象具有可用于执行任何清理的析构函数。

于 2014-04-09T14:03:30.903 回答