Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于恢复以前值的RAII对象 也许我正在考虑这个问题,但是考虑下面的例子: bool some_state = false; // ... later ... some_state = true; do_something(); some_state = false;_C++_Boost_C++03 - Fatal编程技术网

C++ 用于恢复以前值的RAII对象 也许我正在考虑这个问题,但是考虑下面的例子: bool some_state = false; // ... later ... some_state = true; do_something(); some_state = false;

C++ 用于恢复以前值的RAII对象 也许我正在考虑这个问题,但是考虑下面的例子: bool some_state = false; // ... later ... some_state = true; do_something(); some_state = false;,c++,boost,c++03,C++,Boost,C++03,现在想象一下,do\u something()可以抛出。我们不会将某些状态设置回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

现在想象一下,
do\u something()
可以抛出。我们不会将
某些状态设置回
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)

boost有这样的东西吗?当然,我可以写我自己的东西,但我想确保我没有首先重新发明轮子。我在MSVC上使用C++ 03,所以我不能使用任何新奇的新C++ 11:(< /P> < p>你正在调用正确的树。Bjarne Stroustrup强烈建议RAII进行异常处理,而不是尝试/捕获/最后。在最新版本的C++编程语言(第四版)中。,他在第13章“异常处理”中完整地概述了他推荐的方法

替换一整章是相当困难的,因此首先,我建议只阅读这一章。然而,基本思想是使用组合,让构造函数保护资源

因此,如果类A保护3个资源,每个资源可能会抛出(可能是一些内存),那么您可以让子对象在其构造函数(而不是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进行保护

这里还有一个关键点。您应该在每个子对象的类中只保护一个资源。这样,可以获取资源并允许构造函数退出(从而确保调用析构函数,从而安全释放资源)或抛出(因此,不获取资源).

Boost确实有类似的功能。它被称为state\u saver。它有点隐藏在序列化库中,但它是有文档记录的,而且显然是官方的(即不在某些详细名称空间中)


演示:

更多的是编码风格问题,而不是语言本身。只需使用
try/catch
。@billz try/catch用于异常处理,这不是正常的预期逻辑。抛出也会影响性能。这不是一个可接受的解决方案。RAII不是编码风格首选项,它是一种设计模式。有,但我不确定用法:
BOOST\u SCOPE\u EXIT(some\u state=true);
是的,OP只是想要一个scopeguard,而ScopeExit似乎是一个scopeguard。@Robert Dailey 1.37已经5岁了。。。