2

次のようなコードがあります。

void writeToStream( std::ostream & outputStream )
{
    MyXmlWriter xmlWriter{ outputStream };
    xmlWriter.addNode();
    xmlWriter.addNode();
    xmlWriter.close(); // should this be called in `MyXmlWriter` destructor?
}

close 関数はいくつかの xml 終了タグを書き込み、ファイルを適切に解析できるようにします。コンストラクターは、xml ファイルのヘッダーを書き込みます。xmlWriter.close();クリーンアップコードを検討することができます。C++ では、クリーンアップ コードをデストラクタに入れることが一般的なアドバイスです。これにより、適切にクリーンアップすることを忘れることはありません。ただし、この場合、クリーンアップ コードがスローされる可能性があります。(例外が有効になっている可能性があると想像してくださいfile。ファイルへの書き込みが失敗する可能性があります。) したがって、close()関数がデストラクタで呼び出された場合、スローされたすべての例外を食べる try-catch ブロックでラップする必要があります。

MyXmlWriter::~MyXmlWriter() 
{
    try
    {
        close();
    }
    catch (...)
    {
    }
}

ただし、この場合、発信者にはエラーが通知されません。この関数writeToStream()は、呼び出し元が知らないうちに xml の終了タグをファイルに書き込めない可能性があります。この状況でのベストプラクティスは何ですか?

4

2 に答える 2

5

例外を飲み込むことは、そもそもスローの目的に反するため、通常は「最悪の方法」です。

ただし、この場合、実際にはデストラクタの機能のサブセットのみが必要であり、「ボーナス」であるフラッシュは含まれませんが、スローされる可能性があります。ネットワーク タイムアウトがすでに発生している場合に不必要に待機するなど、まったくフラッシュしようとすると副作用が発生する可能性があります。

James Kanze が述べたように、ベスト プラクティスは、デストラクタが実行される前に手動でフラッシュすることです。これにより、デストラクタでの例外的な状態が排除されます。

将来的には、C++ がトランザクションをより適切にサポートする可能性があります。しかし、今のところ、あなたのアプローチは合理的です。いずれにせよ、デストラクタがstd::filebuf動作するように指定されている方法は次のとおりです。

効果:クラス のオブジェクトを破壊しますbasic_filebuf<charT,traits>。呼び出しますclose()。への呼び出しを含め、オブジェクトの破棄中に例外が発生した場合、close()例外はキャッチされますが、再スローされません (17.6.5.12 を参照)。

于 2013-12-20T10:12:26.807 に答える