有没有办法告诉程序正在抛出异常?

时间:2017-10-25 04:18:37

标签: c++ c++11 exception exception-handling

我的问题的简短版本

在堆栈上分配了A类型的对象。在它的析构函数~A()中,是否有一种方法可以判断析构函数是否被调用,因为抛出了异常并且堆栈正在展开,或者只是因为它定义的范围“自然地”结束了?我尝试检查<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script>var $j = jQuery.noConflict();</script> <script type="text/javascript"> $j(document).ready(function(){ var counter = 2; $j("#addButton").click(function () { if(counter>60){ alert("Max 60 Standard Shutters Per Order"); return false; } var newStandardDiv = $j(document.createElement('div')) .attr({"name":'StandardDiv' + counter, "id":'StandardDiv' + counter,}); newStandardDiv.after().html( '<span style="margin-right:15px">Room: ' + '<input class="text" type="text" name="sroom' + counter + '" id="sroom' + counter + '" style="width:100px; margin-bottom:10px">' + '</span>' + '<span style="margin-right:15px; height=90px">Width: ' + '<input class="text" type="number" name="swidth' + counter + '" id="swidth' + counter + '" style="width:50px; margin-bottom:10px" step="0.125" min="0" title="Measurements in decimal point values.">' + '</span>' + '<span style="margin-right:15px">Height: ' + '<input class="text" type="number" name="sheight' + counter + '" id="sheight' + counter + '" style="width:50px; margin-bottom:10px" step="0.125" min="0" title="Measurements in decimal point values.">' + '</span>' + '<span style="margin-right:15px">Sq. Ft. Rect.' + '<input class="text" type="number" name="ssqfoot' + counter + '" id="ssqfoot' + counter + '" style="width:50px; margin-bottom:10px" readonly />' + '</span>' + '</div>' ); newStandardDiv.appendTo("#StandardGroup"); var objDiv = document.getElementById("StandardGroup"); objDiv.scrollTop = objDiv.scrollHeight; counter++; }); $j("#removeButton").click(function () { if(counter==2){ alert("Nothing To Remove"); return false; } counter--; $j("#StandardDiv" + counter).remove(); }); }); </script> <div id="StandardGroup" style="max-height:440px; overflow-y: scroll; margin-bottom:2px"> <div id="StandardDiv1" > <span style="margin-right:15px">Room: <input class="text" type="text" name="sroom1" id="sroom1" style="width:100px; margin-bottom:10px"></span> <span style="margin-right:15px; height=90px">Width: <input class="text" type="number" name="swidth1" id="swidth1" style="width:50px; margin-bottom:10px" step="0.125" min="0" title="Measurements in decimal point values." value=""></span> <span style="margin-right:15px">Height: <input class="text" type="number" name="sheight1" id="sheight1" style="width:50px; margin-bottom:10px" step="0.125" min="0" title="Measurements in decimal point values."></span> <span style="margin-right:15px">Sq. Ft. Rect. <input class="text" type="number" name="ssqfoot1" id="ssqfoot1" style="width:50px; margin-bottom:10px" readonly /></span> </div> </div> <input type="button" class="button light" value="+" id="addButton" style="height:25px; width:25px; padding:2px 2px 2px 2px; margin-left:13px;"> <input type="button" class="button light" value="-" id="removeButton" style="height:25px; width:25px; padding:2px 2px 2px 2px;"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>是否为空,不起作用。

更长版本

我有一个旧的API我必须支持:

std::current_exception

如果void MyApi() { try { MyTimeTracker mtt; //do API stuff } catch(...) { //handle exception } } 抛出异常,则表示API失败,否则表示成功。 MyTimeTracker检查执行API stuff需要多长时间 - 它测量构造函数中的开始时间和析构函数中的结束时间并将其报告给数据库。

现在我希望它还报告API调用是否成功。有没有办法在析构函数中告诉它?

我不允许在第一个API stuff块之外分配它,因为整个API代码必须在try块中。我可以将try放入第一个内部的单独try块中,然后重新抛出,但这看起来很难看。

我尝试在析构函数中检查API stuff,但它是null,即使我们正在抛出异常。

1 个答案:

答案 0 :(得分:3)

没有像您描述的那样检测堆栈展开状态的标准可移植方式。

但是有一个更简单的解决方案。将一个布尔成员添加到MyTimeTracker,如果API成功则设置它,然后在析构函数中进行检查。

MyTimeTracker::MyTimeTracker()
{
    ...
    success = false;
}

MyTimeTracker::~MyTimeTracker()
{
    ...
    if (!success) {
        ... 
    }
}

void MyApi()
{
    try
    {
        MyTimeTracker mtt;
        //do API stuff
        mtt.success = true;
    }
    catch (...)
    {
        //handle exception
    }
}

<强>更新

  

完成所有操作的主要原因是报告错误代码,该代码位于异常位置。

然后你必须求助于第二个try/catch来获取错误代码,将其存储在mtt对象中以在析构函数中执行操作,然后重新抛出:

MyTimeTracker::MyTimeTracker()
{
    ...
    errCode = 0;
}

MyTimeTracker::~MyTimeTracker()
{
    ...
    if (errCode != 0) {
        ... 
    }
}

void MyApi()
{
    try
    {
        MyTimeTracker mtt;
        try
        {
            //do API stuff
        }
        catch (const the_api_error &e)
        {
            mtt.errCode = ...; // error code from e... 
            throw;
        }
    }
    catch (...)
    {
        //handle exception
    }
}