如何处理和避免递归

How to handle and avoid Recursions

本文关键字:递归 处理 何处理      更新时间:2023-10-16

我正在使用自定义类来管理自动售货机。我不知道为什么它不断抛出堆栈溢出错误。我的程序有两个版本,第一个是通过预定义某些变量来查看类等是否工作的基本测试。第二个版本应该是这样的,每次运行程序时,有问题的变量都可以更改(取决于用户输入(。

如果有人能提出避免这种递归或堆栈溢出的方法,我会很棒。以下是所涉及的三个类的代码;

class Filling
{
protected:
    vector<Filling*> selection;
    string fillingChosen;
public:
    virtual float cost()
    {
        return 0;
    }
    virtual ~Filling(void)
    {
        //needs to be virtual in order to ensure Condiment destructor is called via Beverage pointer
    }
};
class CondimentDecorator : public Filling
{
public:
    Filling* filling;
    void addToPancake(Filling* customerFilling)
    {
        filling = customerFilling;
    }
    ~CondimentDecorator(void)
    {
        delete filling;
    }
};

class Frosted : public CondimentDecorator
{
    float cost()
    {       //ERROR IS HERE//
        return (.3 + filling->cost());
    }
};

下面是用于调用上述"成本"函数的代码;

void displayCost(Filling* selectedFilling)
{
    cout << selectedFilling->cost() << endl;
}

下面是启动这一切的代码的一部分(main 方法(;

Filling* currentPancake = NULL;
            bool invalid = true;
            do
            {
                int selection = makeSelectionScreen(money, currentStock, thisState);
                invalid = false;
                if (selection == 1)
                {
                    currentPancake = new ChocolateFilling;
                }
                else if...
.
.
.
.
                else
                    invalid = true;

            } while (invalid);
            bool makingSelection = true;
            CondimentDecorator* currentCondiment = NULL;
                do
                {
                    int coatingSelection = makeCoatingSelectionScreen(money, currentStock, thisState);
                    if (coatingSelection == 1)
                        currentCondiment = new Frosted;
                    else if (coatingSelection == 2)...
.
.
.
                    else if (coatingSelection == 0)
                        makingSelection = false;
                    currentCondiment = thisSelection;
                    currentCondiment->addToPancake(currentPancake);
                    currentPancake = currentCondiment;
                    displayCost(currentPancake);

//Below is the code that DOES work, however it is merely meant to be a test. The 
//above code is what is needed to work, however keeps causing stack overflows
//and I'm uncertain as to why one version works fine and the other doesn't
                    /*currentCondiment = new Frosted;
                    currentCondiment->addToPancake(currentPancake);
                    currentPancake = currentCondiment;
                    displayCost(currentPancake);
                    currentCondiment = new Wildlicious;
                    currentCondiment->addToPancake(currentPancake);
                    currentPancake = currentCondiment;
                    displayCost(currentPancake);*/

                } while (makingSelection);
                displayCost(currentPancake);

                delete currentPancake;

当您使用filling也是FrostedFrosted调用displayCost时,会发生无限递归。这就在这里发生:

currentCondiment->addToPancake(currentPancake);
currentPancake = currentCondiment;
displayCost(currentPancake);

currentCondimentfilling设置为 currentPancake ,然后使用 currentCondiment 调用displayCost


在此过程中,您还会泄漏最初分配给currentPancake的内存。

顺便说一句,currentCondiment = thisSelection;也会泄漏内存。

想法:使用像std::unique_ptr这样的智能指针来消除泄漏。