RAII object for restoring previous value

好久不见. 提交于 2019-12-05 07:44:32

Boost does have something like this. It's called state_saver. It's kind of buried in the serialization library, but it is documented and apparently official (i.e. not in some detail namespace).

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

Demo: http://rextester.com/NVXUG70771

You're barking up the right tree. Bjarne Stroustrup strongly recommends RAII for exception handling as opposed to try/catch/finally. In the latest edition of The C++ Programming Language (4th edition), he completely outlines his recommended method in Chapter 13, Exception Handling.

It's pretty hard to substitute an entire chapter, so first off, I'd recommend just reading the chapter. However, the essential idea is to use composition and let the constructor secure the resource.

So, if you have class A that secures 3 resources that may each throw (perhaps some memory), you instead let the subobject secure each in its constructor (not A's constructor). The key point is that, if the constructor is allowed to complete, it is guaranteed (by the language) that the destructor will be invoked. So, in the top-level constructor initialize the subobjects like this:

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;

}

Just imagine that class C and class D exist and they are structured like B. So, in your example above, some_state will be secured via a class like B, C or D.

Another key point here. You should only secure a single resource in each subobject's class. That way, the resource gets acquired and the constructor is allowed to exit (thus ensuring the destructor gets invoked which will safely release the resource) or it throws (therefore, not acquiring the resource).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!