4

在我目前正在处理的程序中,许多对象包括与对象一起存在的状态变量。例如,在 3d 模型中表示一个点的对象可能包含一个变量来控制该点是否已被选中进行编辑。很规律地,这些状态变量中的一个或多个将被一段代码临时修改,例如

void MyFunc();
{
  mytype temp = statevar;
  statevar = newvalue;
  DoSomething();
  statevar = temp;
}

这有问题,好像DoSomething()抛出异常,statevar没有正确恢复。我计划的解决方法是创建一个新的模板类来恢复其 dtor 中的值。就像是

template<class TYPE> class PushState
{
   PushState(TYPE Var) { Temp = Var; }
   Pop() { Var = Temp; }
   ~PushState() { Pop(); }
   TYPE Temp;
}

void MyFunc();
{
   PushState<mytype> Push(statevar);
   DoSomething();
}

有没有更好的方法来做到这一点,或者有一种公认的将变量推送到堆栈的方法?

4

2 回答 2

3

另一种选择是使用临时 RAII 类。

例如:

void MyFunc();
{
    class Finally {
        mytype temp;
    public:
        Finally( ) { temp = statevar; }
        ~Finally() {
            statevar = temp;
        }
    } finally;

    statevar = newvalue;
    DoSomething();
}

无论函数正常返回还是抛出异常,析构函数finally都会在超出范围时自动调用。

于 2013-05-10T14:11:29.680 回答
2

您可以使用Boost.ScopeExit。这将实例化一个对象,其析构函数将执行范围退出代码。它只是为您隐藏了所有样板代码。

#include <boost/scope_exit.hpp>

void MyFunc() {
    mytype temp = statevar;
    statevar = newvalue;
    BOOST_SCOPE_EXIT(&statevar) {
        statevar = temp;
    } BOOST_SCOPE_EXIT_END
    DoSomething();
}
于 2013-05-10T14:53:18.307 回答