【问题标题】:Is there a generic way to preserve state variables on the stack in C++?是否有一种通用的方法可以在 C++ 中保留堆栈上的状态变量?
【发布时间】:2013-05-10 13:49:35
【问题描述】:

在我目前正在处理的程序中,许多对象包括与对象一起存在的状态变量。例如表示 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();
}

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

【问题讨论】:

  • 这听起来像scope_guard
  • @Pubby 也是我的第一个想法,如果可能的话会投票两次...
  • 谢谢 Pubby,必须查一下。下面的 DrDobbs 文章看起来很有希望; drdobbs.com/cpp/generic-change-the-way-you-write-excepti/…?
  • 另一种方法是修改数据的 副本 而不是原始数据并使用这些数据,并且只有在您确定已成功完成工作时将这些值移动到它们的最终目的地使用不会像交换那样抛出的东西。

标签: c++ variables state


【解决方案1】:

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

例如:

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

    statevar = newvalue;
    DoSomething();
}

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

【讨论】:

    【解决方案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();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-30
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2021-01-28
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多