C++ 是否有一种简单的方法将变量推送到堆栈上以便以后检索

C++ 是否有一种简单的方法将变量推送到堆栈上以便以后检索,c++,recursion,C++,Recursion,我有一个对象的成员函数,它通常以迭代的方式使用,但偶尔以递归的方式使用。该功能基本上是沿着下坡水流的路径,在某些条件下,水流可能会分裂。为了支持偶尔的递归,我必须将对象的状态推到堆栈上,并在后置词中将其弹出。我目前正在使用局部变量进行此操作,但代码看起来很糟糕。我想编写PushState和PopState成员,但我所看到的大多数实现都不是很好。e、 g.在我的对象中使用堆栈成员,最终使用堆,这会导致其他问题_当push函数返回时,堆栈帧丢失,alloca无法工作 有没有其他合理的通用方法来推动和

我有一个对象的成员函数,它通常以迭代的方式使用,但偶尔以递归的方式使用。该功能基本上是沿着下坡水流的路径,在某些条件下,水流可能会分裂。为了支持偶尔的递归,我必须将对象的状态推到堆栈上,并在后置词中将其弹出。我目前正在使用局部变量进行此操作,但代码看起来很糟糕。我想编写PushState和PopState成员,但我所看到的大多数实现都不是很好。e、 g.在我的对象中使用堆栈成员,最终使用堆,这会导致其他问题_当push函数返回时,堆栈帧丢失,alloca无法工作

有没有其他合理的通用方法来推动和弹出堆栈,我错过了

class CMyObject
{   
    enum Direction
    {
      left,right,branch,finished;
    }

    // state variables
    double m_XPos,m_YPos;

    void    Navigate(double x,double y);
    Direction GoLeft();
    Direction GoLeft();
};

void    CMyObject::Navigate(double x,double y)
{
    m_XPos = x; m_YPos = y;

    Direction d = GoLeft(x,y);
    while(d != finished)
    {
        switch(d)
        {
            case left: d = GoLeft(); break;
            case right: d = GoRight(); break;
            case branch:
            {
                // push object state onto the stack
                double temp_x = m_XPos; double temp_y = m_YPos;
                Navigate(m_XPos,m_YPos);
                // pop object state from the stack
                m_XPos = temp_x; m_YPos = temp_x;
                GoRight();
            } break;
        }
    }
}

我想最明显的方法是创建整个对象的副本,然后对其执行递归调用。这样,每个分支都有自己的状态,编译器为您进行堆栈管理。基本上,为了在递归中安全地使用方法,必须对其进行修改。这里的情况并非如此,因为您的方法依赖于持久状态。所以你必须复制这个状态,这意味着复制这个对象

更新:

有关递归和重入的更多链接:

  • 是关于EMEDED系统中的可重入性,但也解释了与递归的关系
  • 关于这个问题
  • (pdf)由第一篇文章的作者撰写

遗憾的是,Donald Knuth尚未完成的第四部分,但当他完成时,请阅读,因为这一点肯定很清楚。

我认为您可能需要两个对象-一个用于保持位置和任何其他状态,另一个用于通过树递归导航第一个对象的实例。这样,当导航器中的递归调用返回时,被导航对象的状态将被恢复。

类似的情况如何

struct Restore {
    Restore(double& value) : m_value(value), m_initial(value) {}
    ~Restore() {m_value = value;}
    double& m_value;
    double m_initial;
};
然后:

{ //scope
    Restore r1(m_XPos), r2(m_YPos);
    Navigate(m_XPos,m_YPos);
} // m_XPos and m_YPos automatically restored when r1 and r2 goes out of scope

您应该阅读您所指的文章,可重入函数可以安全地并发执行(如从多个线程执行),函数无需重入即可递归。请阅读示例部分的最后一句。您可能指的是以“通常”一词开头的句子.我知道我肯定错过了一些显而易见的东西。它是递归分支的额外对象。多亏了这一点,可以想象函数对于递归是可重入的,但是对于线程是不可重入的。POSIX规范使用的公式是:“某些函数不需要是可重入的。不需要是可重入的函数不需要是线程安全的”。因此,我觉得说可重入性和线程安全性是一回事似乎有些奇怪。析构函数不应该是
~Restore(){m_value=m_initial;}
?它不会按照您编写的方式编译(
~Restore(){m_value=value;}
),因为析构函数中没有定义
value