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() はそれを呼び出しません。正しいのは use 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::ofstreamcommit 関数を使用してこれを頻繁に行います。ファイル名を取得して開くのはコンストラクターです。このcommit関数はファイルを閉じ、閉じに成功すると、ファイルがコミットされたことを示すフラグを設定します。デストラクタはフラグをテストし、ファイルがコミットされていない場合は、ファイルを閉じて削除し、部分的なファイルが残らないようにします。

于 2014-04-09T14:15:15.277 に答える