0

我有一段网络代码抛出各种异常,这些异常都被一般的 catch 异常语句捕获。

try {
    network code
} catch (Exception e) {
    freeaddrinfo(some_address);
}

此方法的问题是异常中的 freeaddrinfo。并非所有异常情况都可以/应该调用 freeaddrinfo 并且在我的特定情况下,当传递到网络代码以连接某处的无效地址时,不应调用 freeaddrinfo。我解决此问题的想法是检索此异常引发的错误代码,并可能将其与 e.to_string 结合使用来处理此边缘情况。根据我从 Effective Java 中学到的知识,这是一种处理这个问题的脆弱方法。你建议我应该怎么做?

4

3 回答 3

2

在 C++ 中,异常后释放资源的常用方法不是捕获异常,而是将资源包装在析构函数负责释放的对象中。这样,当管理对象超出范围(或以其他方式销毁)时,无论是否引发异常,它都会被释放。这种技术被称为RAII

一个(非常基本的)管理对象可能如下所示:

struct AddressInfo {
    addrinfo * info;

    // Constructor takes ownership of resource
    explicit AddressInfo(addrinfo * info) : info(info) {}

    // Destructor releases resource
    ~AddressInfo() {freeaddrinfo(info);}

    // Prevent shallow copying, so only one object manages the resource
    AddressInfo(AddressInfo const &) = delete;
    void operator=(AddressInfo const &) = delete;
};

然后您的代码将变为:

// some network code
AddressInfo address(some_address);
// some more network code

无需任何异常处理或手动清理代码。

于 2012-08-06T15:14:05.347 回答
1

如果你坚持使用异常,那么网络代码应该根据错误的性质提出一个非常具体的异常(类型)。也就是说,网络代码应该引发一个异常,就其本质而言,它暗示是否freeaddrinfo()可以调用。

于 2012-08-06T15:00:45.230 回答
0

创建更具体的异常并抛出它们?然后你可以先抓住那些,然后再回到一般的捕获。

try {
network code
} 
catch (SomeException1 e) { freeaddrinfo(some_address); }
catch (SomeException2 e) { freeaddrinfo(some_address); }
catch (Exception e) { }
于 2012-08-06T15:09:51.060 回答