5

ウィキペディアのファイル I/O の RAII の典型的な例では、ファイルを閉じるときに発生するエラーはすべて飲み込まれます。

#include <iostream>
#include <string> 
#include <fstream>
#include <stdexcept>

void write_to_file (const std::string & message) {
    // try to open file
    std::ofstream file("example.txt");
    if (!file.is_open())
        throw std::runtime_error("unable to open file");

    // write message to file
    file << message << std::endl;

    // file will be closed when leaving scope (regardless of exception)
}

fileが自動的に閉じられたときにエラーが発生したかどうかを判断する方法がないようです。スコープ内にあるfile.rdstate()間だけ呼び出すことができるのは明らかです。file

手動で呼び出しfile.close()てエラーをチェックすることもできますが、スコープから戻るすべての場所でそれを行う必要があり、RAII の目的に反します。

ファイルシステムの破損などの回復不可能なエラーのみがデストラクタ内で発生する可能性があるとコメントしている人もいますが、デストラクタがファイルを閉じる前にファイルをフラッシュし、フラッシュ中に回復可能なエラーが発生する可能性があるため、それは真実ではないと思います。

では、破壊中に発生するエラーを取得するための一般的な RAII の方法はありますか? デストラクタから例外をスローすることは危険であるため、正しいアプローチとは思えません。

私が考えることができる最も簡単な方法は、破壊中にエラーが発生した場合にデストラクタが呼び出すコールバック関数を登録することです。驚いたことに、これが によってサポートされているイベントはないようですios_base::register_callback。私が何かを誤解していない限り、それは大きな見落としのようです。

しかし、おそらくコールバックは、最新のクラス設計で破棄中にエラーを通知する最も一般的な方法でしょうか?

デストラクタで任意の関数を呼び出すことも危険だと思いますが、おそらく呼び出しをtry/catchブロックでラップすることは完全に安全です。

4

2 に答える 2