如何处理和避免递归

时间:2015-03-18 01:14:56

标签: c++ recursion stack-overflow

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

如果有人可以建议避免这种递归或堆栈溢出的方法,我会很高兴。以下是涉及的三个类的代码;

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;
}

以下是启动它的代码的一部分(主要方法);

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;

1 个答案:

答案 0 :(得分:3)

当您使用displayCost Frosted同时filling来调用Frosted时,会发生无限递归。这就发生在这里:

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

您将filling的{​​{1}}设置为currentCondiment,然后使用currentPancake致电displayCost


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

Btw currentPancake也会泄漏内存。

想法:使用currentCondiment = thisSelection;之类的智能指针来消除泄漏。