7

インタビューでこの質問に直面する前のある日。だからただ私を案内してください。

c++でコンストラクタから例外がスローされた場合、初期化されたリソースをクリーンアップする方法は?

4

4 に答える 4

6

コツはRAII(リソース取得は初期化)を使ってリソースを管理することです。

ポインター メンバーがある場合は、コンストラクターから例外がスローされると自動的にクリーンアップ ジョブを実行する生のポインターの代わりにスマート ポインターを使用します。

よく読んでください:
Herb Sutter の優れた GotW 記事「Construction Failures」

于 2012-10-04T08:45:59.617 に答える
1

リソースが破棄されたときにリソースを解放するデータ メンバー (別名 RAII) を使用します。

例えば:

struct TwoStrings {
    std::string string1;
    std::string string2;
    TwoStrings(const std::string &input) : string1(input) {
        if (!input[1] == ':') {
            throw std::logic_error('not a Windows absolute path');
            // yes, absolute paths can begin \\, this is a toy example
        }
        if (input.back() == '\\') {
            string2 = input;
        } else {
            string2 = input + "\\";
        }
    }
};

logic_errorコンストラクターが (またはのいずれか)をスローするbad_allocと、既に初期化されているデータ メンバーstring1が破棄され、リソースが解放されます。さらに言えばstring2も破棄されますが、コンストラクターがスローした場合string2はまだ空でなければならないため、特に影響はありません。

stringはリソースを管理するクラスの例ですが、他にもたくさんあります。それらの中で最も柔軟なものは「スマート ポインター」と呼ばれ、文字の自己割り当て配列だけでなく、ほぼすべてのリソースを管理するように構成できますstring

于 2012-10-04T08:53:02.723 に答える
1

例外がスローされると、スタックはキャッチ ポイントまで展開されます。その結果、その中で構築されていたすべてが破壊されます。

ポイントは、すべての賢明なリソースを、デストラクタが関連するリソースの破棄を処理するクラスにラップすることです。

リソースがヒープに割り当てられたオブジェクトである場合、スマート ポインターはまさにそれを行います (破棄時にポイントされたオブジェクトを削除します)。リソースが開いているファイルである場合、ストリームは破棄時にそれを閉じます。それ以外の場合は、カスタム ラッパーが必要です。

ただし、多くの「リソース」は、それ自体が void* であるハンドラーによって表されることに注意してください。これにより、割り当てられたリソースで初期化し、削除関数を指定することで、スマートポインターも使用できます。

テクニックがうまく機能するかどうかは、好みと機会の問題です。

于 2012-10-04T08:53:41.007 に答える
1

最善の方法は次のとおりです。コンストラクタでリソースを割り当て、デストラクタで割り当てを解除します。

C++ のテンプレートは、オブジェクトの作成をアトミックにできるため、この目的に非常に役立ちます。

于 2012-10-04T08:56:57.090 に答える