6

おそらく私はこれを考えすぎていますが、次の例を考えてみてください。

bool some_state = false;

// ... later ...

some_state = true;
do_something();
some_state = false;

do_something()今、それが投げることができると想像してください。some_stateに戻ることはありませんfalse。以前の値を記憶するために、スコープに基づいてプッシュ/ポップするある種の自動スタックがあると便利です。

{
    scoped_restore res( some_state, true ); // This sets some_state to true and remembers previous value (false)
    do_something();
} // At this point, res is destroyed and sets some_state back to false (previous value)

ブーストにはこんなものがありますか?もちろん、私は自分のオブジェクトを書くことができますが、最初に車輪を再発明していないことを確認したいと思います. 私は MSVC で C++03 を使用しているため、残念ながら新しい C++11 を使用することはできません :(

4

2 に答える 2

1

ブーストにはこのようなものがあります。これは state_saver と呼ばれます。シリアライゼーション ライブラリに埋もれているようなものですが、文書化されており、明らかに公式です (つまり、詳細な名前空間ではありません)。

http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/state_saver.html

デモ: http://rextester.com/NVXUG70771

于 2016-06-17T17:01:02.137 に答える
0

あなたは正しい木に向かって吠えています。Bjarne Stroustrup は、try/catch/finally ではなく、例外処理に RAII を強く推奨しています。The C++ Programming Language (第 4 版) の最新版では、第 13 章「例外処理」で推奨される方法を完全に概説しています。

章全体を置き換えるのはかなり難しいので、最初は章だけを読むことをお勧めします. ただし、本質的な考え方は、コンポジションを使用し、コンストラクターにリソースを確保させることです。

したがって、それぞれがスローする可能性のある 3 つのリソース (おそらくメモリ) を保護するクラス A がある場合、代わりに、サブオブジェクトがそのコンストラクター (A のコンストラクターではなく) でそれぞれを保護できるようにします。重要な点は、コンストラクターの完了が許可されている場合、デストラクタが呼び出されることが (言語によって) 保証されるということです。したがって、トップレベルのコンストラクターで、次のようにサブオブジェクトを初期化します。

class B{

    public:

        B( int n )
        {
            //allocate memory (may throw)
        }

        void *secured_memory;

        ~B(){
            //release memory        
        }

}


class A{

    public:

        A( int n )
            :b{n}, c{n}, d{n}
        {
            //will not complete if B, C or D throws
            //but because the constructors of B and C completed
            //their destructors will be invoked if D throws         
        }

        B b;
        C c;
        D d;

}

クラス C とクラス D が存在し、それらが B のように構造化されていると想像してみてください。したがって、上記の例では、B、C、または D などのクラスを介して some_state が保護されます。

ここでもう一つのキーポイント。各サブオブジェクトのクラスで 1 つのリソースのみを保護する必要があります。そのようにして、リソースが取得され、コンストラクターが終了できるようになります (したがって、リソースを安全に解放するデストラクタが呼び出されることが保証されます)、またはスローされます (したがって、リソースを取得しません)。

于 2013-07-24T04:28:57.583 に答える