0

さまざまな例外をスローするネットワークコードがありますが、これらはすべて一般的なcatch例外ステートメントでキャッチされます。

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

このメソッドの問題は、例外内のfreeaddrinfoです。例外のすべてのケースでfreeaddrinfoを呼び出すことができる/すべきではありません。私の特定のケースでは、どこかに接続するためにネットワークコードに渡される無効なアドレスがある場合、freeaddrinfoを呼び出すべきではありません。この問題を解決する私の考えは、この例外によってスローされたエラーコードを取得し、これをe.to_stringと組み合わせて使用​​してこのエッジケースを処理することです。私がEffectiveJavaから学んだことから、これはこの問題に対処するための脆弱な方法です。あなたは私が何をすべきかをお勧めしますか?

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 に答える