2

非const参照によってスタック上に構築されたオブジェクトをtry-blockにスローし、それをキャッチして変更してから、別のcatchブロックを参照してスローすることに問題はありますか?

以下は私が参照しているものの短い例です。

struct EC {
    EC(string msg) { what = msg; }
    string where;
    string what;

    void app(string& t) { where += t; }
    string get() { return what; }
};

try {
    try {
        try {
            EC error("Test");
            throw error;
        }
        catch (EC& e) {
            e.app("1");
            throw e;
        }
    }
    catch (EC& e) {
        e.app("2");
        throw e;
    }
}
catch (EC& e) {
     e.app("3");
     cout << e.where << endl;
     cout << e.get() << endl;
}

これにより、e。何にジャンクが含まれる可能性がありますが、e。どこにそのまま残る可能性がありますか?例:
e.where is "123"
e.get()は、ヌルバイトに到達するまで、大量のガベージデータを返します。

4

1 に答える 1

8

「参照で投げる」というものはありません。それは単に不可能です。そのための構文はありません。「参照をスロー」しようとするたびに、参照されたオブジェクトのコピーが実際にスローされます。言うまでもなく、コード内で参照によってスローする試みはありません。

以前にスローされた例外を参照によって(非constのものでも)キャッチし、それを介して一時例外オブジェクトを変更することができます。それが動作します。実際、新しい例外オブジェクトを作成する代わりに、現在変更されている既存の例外オブジェクトを再スローできます。つまり、あなたはただすることができます

throw;

それ以外の

throw e;

catch句で、正しく動作するコードを取得します。つまり、元のオブジェクト(変更を加えたもの)は、ハンドラー階層を介して飛行を継続します。

ただし、コードの形式が正しくありません。

e.app("1"); 

appパラメータが非定数参照であるため、呼び出し(およびその他のへの呼び出し)。app宣言を次のいずれかに変更します

void app(const string& t) { where += t; }  // <- either this
void app(string t) { where += t; }         // <- or this

コンパイルするために。

それ以外の場合は、コードは正常に機能するはずです。からゴミを取得することは想定されていませんget()。もしそうなら、それはあなたのコンパイラかあなたが示さないあなたのコードの問題のどちらかであるに違いありません。

于 2010-02-16T17:19:15.533 に答える