提取try-catch时出现运行时错误

时间:2017-08-22 14:15:39

标签: c++ runtime

所有代码:https://pastebin.com/k7TZzQEY

/*If i remove try catch runtime error appear.*/ 
try
    {
        SnowAdventure.DodajUplatu(nisvet, trening_1, uplata_1, "trening");
        SnowAdventure.DodajUplatu(nisvet, trening_2, uplata_2, "trening");
        SnowAdventure.DodajUplatu(nisvet, trening_3, uplata_3, "trening");
        SnowAdventure.DodajUplatu(nisvet, trening_1, oprema_nm, "oprema");
        SnowAdventure.DodajUplatu(nisvet, trening_3, oprema_NM, "oprema");

    }
    catch (const std::exception& obj)
    {
        obj.what();

    }
/*Function*/
void DodajUplatu(Ucenik & ucenik, Trening & trening, Uplata & uplata, string svrha) {
        for (int i = 0; i < _treninzi.size(); i++)
        {
            for (int j = 0; j < _treninzi[i].getUcenici().size(); j++)
            {
                if (*_treninzi[i].getUcenici()[j] == ucenik) {
                    if (svrha == "oprema") {
                        int size = _treninzi[i].getUcenici()[j]->getIznajmljenaOprema()->size();
                        bool uplaceno = false;
                        for (int k = 0; k < size; k++)
                        {
                            Oprema * oprema = &(*_treninzi[i].getUcenici()[j]->getIznajmljenaOprema())[k];
                            if (oprema->getCijena() >= uplata.getIznos()) {
                                _treninzi[i].getUcenici()[j]->DodajUplatu(uplata, svrha);
                                uplaceno = true;
                                return;
                            }
                        }
                        if (!uplaceno) {
                            throw exception("Niste uplatili!");
                            return;
                        }
                    }
                    else
                    {
                        if (trening.getTipTreninga() == Pocetnicki) {
                            if (uplata.getIznos() == trening.getBrojCasova() * 10) {
                                _treninzi[i].getUcenici()[j]->DodajUplatu(uplata, svrha);
                                return;
                            }
                            else {
                                throw exception("Niste uplatili dovoljno novca!");
                            }
                        }
                        else if(trening.getTipTreninga()==Rekreativni)
                        {
                            if (uplata.getIznos() == trening.getBrojCasova() * 15) {
                                _treninzi[i].getUcenici()[j]->DodajUplatu(uplata, svrha);
                                return;
                            }
                            else {
                                throw exception("Niste uplatili dovoljno novca!");
                            }
                        }
                        else
                        {
                            if (uplata.getIznos() == trening.getBrojCasova() * 20) {
                                _treninzi[i].getUcenici()[j]->DodajUplatu(uplata, svrha);
                                return;
                            }
                            else {
                                throw exception("Niste uplatili dovoljno novca!");
                            }
                        }
                    }
                }
                throw exception("Nepoznat ucenik koji je zaprimljen kao parametar!");
            }
        }

    }

1 个答案:

答案 0 :(得分:2)

cppreference.com说:

  

一旦构造了异常对象,控制流就会起作用   向后(向上调用堆栈),直到它到达尝试的开始   块,此时关联的catch块的参数   与抛出的表达式进行比较以找到匹配项。如果不匹配   找到后,控制流程继续展开堆栈直到   接下来尝试阻止,依此类推。如果找到匹配,则控制流跳转   到执行的匹配catch块(异常处理程序)   通常

     

当控制流向上移动调用堆栈时,将调用析构函数   对于所有具有自动存储持续时间的对象   以相反的构造顺序输入相应的try-block。   如果从构造函数抛出异常,则调用析构函数   适用于所有完全构造的非静态非变体成员和基础   类。此过程称为堆栈展开。

<强>解释

  当我从代码

中删除try catch块时,已调用

abort()

这意味着如果您的代码抛出异常(函数DodajUplatu确实如此),并且此异常未在try / catch块中处理(如果将其删除则不行),{{ 1}} - 调用运行时错误。

  

使用try catch它可以很好地工作

是的,因为此异常是在catch块中捕获的。

您应该阅读exceptions以获取扩展信息。 或者更好地阅读一些C++ book