4

我读了这篇文章,发现处理异常很重要,我使用nlohmann::json(来自github)并且几乎在我的大多数成员函数中都使用了它,如果输入有问题nlohmann::json::parsenlohmann::json::dump它就有机会抛出异常。

所以我需要处理那些抛出异常的机会,如下所示:

bool my_class::function(const std::string& input) const
try
{
    using namespace nlohmann;

    const auto result = json::parse(input);
    const auto name = result["name"].dump();

    /* and ... */
}
catch (const std::exception& e)
{
    /* handle exception */
}

但我想知道哪一行代码抛出异常,所以如果我写这样的东西:

bool my_class::function(const std::string& input) const
{
    using namespace nlohmann;

    try
    {
        const auto result = json::parse(input);
    }
    catch(const std::exception& e)
    {
        /* handle exception */
    }

    try
    {
        const auto name = result["name"].dump();
    }
    catch(const std::exception& e)
    {
        /* handle exception */
    }

    /* and ... */
}

它给我留下了数千个 try-catch 块。为什么处理异常更好?

4

2 回答 2

5

我会这样:设置一个“序列指针”以记录您尝试解析的位置/内容,就像使用模式尝试解析的字符串一样......这样您就可以知道/通知确切的位置json 中的错误元素。

看下面的例子,如果“名称有问题,那么 r 持有值”试图解析名称“所以在异常中你有关于什么 json 元素导致问题的信息:)

bool my_class::function(const std::string& input) const
{
    std::string r{""};
    try
    {
        using namespace nlohmann;
        r="trying to parse input";
        const auto result = json::parse(input);

        r="trying to parse name";
        const auto name = result["name"].dump();

        r="trying to parse age";
        const auto age = result["age"].dump();

        /* and ... */
    }
    catch (const std::exception& e)
    {
        /* handle exception */
    }
}
于 2020-06-16T06:57:48.943 回答
3

您可能已经注意到,C++ 没有此信息可用。@ΦXocę웃Пepeúpaツ 提供了一些很好的解决方法。

让我提供一些其他观点,作为您程序的最终用户,我对程序失败的代码行不感兴趣。我提供的 JSON 是正确的还是不正确的。在第二种情况下,我想知道我需要做什么才能修复 JSON。查看定义异常的代码,这看起来非常详细。

你对它感兴趣的那一刻是你在程序中写了一个错误并且你得到了意想不到的错误。在那个时间点,您最好将调试器附加到您的程序并单步执行它,同时中断任何异常的抛出。这不仅会为您提供行号,还会为您提供堆栈上的所有可用信息……我可以建议对您的代码编写单元测试,这样您就有了必须调试的小段代码。理想情况下,如果您仍然在程序中遇到未发现的错误,您甚至可以将失败案例减少到新的单元测试。

最后,性能论点。拥有更多细节需要收集更多细节。这种收集是有代价的。在其他编程语言(如 Java)中,您可以向异常请求调用堆栈,而在 C++ 中,异常是最低限度的。尽管跟踪行号可能不会那么昂贵,但它确实需要最终用户不需要的额外汇编指令。

简而言之,该语言没有提供获取行号的便捷方法。这是因为有更好的方法来获取这些信息等等:你的调试器。

于 2020-06-16T07:28:12.990 回答