定义异常类

时间:2018-03-19 18:55:46

标签: c++ exception

我想知道为给定程序定义自己的异常类通常是一个好习惯。例如,我有一个程序,主要是读取/写入文件,并修改iptables规则。我也把程序写成了自己的基本记录器类。要处理意外值或错误(如打开文件),我通常使用std::runtime_error。我想知道定义我自己的异常类通常是个好主意。例如:

void Protocol::set_port(const unsigned long &port) {
    if ( (port > 0) && (port < 65535) ) {
        port_ = port;
    }
    else {
        throw std::invalid_argument("Invalid port number");
    }
}

我不喜欢使用一大堆try和catch块,因为我发现这是一个糟糕而丑陋的练习(虽然我可能错了)。

1 个答案:

答案 0 :(得分:1)

  

我想知道为给定程序定义自己的异常类通常是一个好习惯。

是的,通常,异常的类型应该描述源或原因,因此您可以通过模式匹配而不是代码来处理该特定异常。

  

我通常使用std :: runtime_error。我想知道定义我自己的异常类通常是个好主意。

是的,一般来说,您应遵循以下规则:

  1. 显然,只使用例外情况来报告异常故障(即前提条件未得到满足,或资源因程序错误操作而无法使用)。

  2. 如果失败是一个逻辑错误(调用者试图在您的程序域中执行非法操作),那么从std::logic_error派生您的例外。

  3. 如果失败是无效参数的结果,那么从std::invalid_argument派生是有意义的。

  4. 如果失败是运行时错误(例如文件丢失),则从std::runtime_error派生。

    嵌套异常也很有用,因为您可以传递摘要和异常原因以供以后诊断,例如:

  5. struct port_out_of_range : std::invalid_argument
    {
        port_out_of_range(std::string const& context, unsigned long given)
        : std::invalid_argument(context + ": port given: " + std::to_string(given))
        {
        }
    };
    
    void Protocol::set_port(const unsigned long &port) 
    {
        if ( port < 65535 ) {
            port_ = port;
        }
        else {
            throw port_out_of_range("Protocol::set_port", port);
        }
    }
    

    ...稍后......

    try {
        // ... some things ...
        foo.set_port(x);
        // ... more things ...
    }
    catch(port_out_of_range& e)
    {
        // maybe some remedial action possible here
    }
    catch(std::exception& e)
    {
        // but not here
        log(e);
        throw;
    }