0

私は現在c++を学習/使用していますが、Javaのバックグラウンドを持っているので、これがばかげた質問である場合はお詫び申し上げます。以下は、外部APIによって生成されたエラーを処理する方法を表すコードです。ただし、エラー処理出力パラメータに値を割り当てると、メモリリークが発生するかどうかはわかりません。

class ExceptionHandler {

private:
    std::string _msg;
    int _code;

public:
    ExceptionHandler(std::string msg = "", int code = 0) : 
         _msg(msg),
         _code(code)
    {
    }

    int code() {
        return _code;
    }
    std::string msg() {
        return _msg;
    }

}

 //This method returns true if it was executed with no errors
 //It returns false if an error occurred

    bool foo(ExceptionHandler * errHandler = NULL) {

        int sts; 

        //The API functions return 0 if completed successfully
        //else they returns some error code

        sts = some_api_func1();

        if(sts != 0) { //An error occurred!
            if(errHandler) {
                ExceptionHandler handler("Error from func1",sts);
                *errHandler = handler; //<--- Will this cause a memory leak since I would be losing errHandler's original value??
            }
            return false;
        }

        //My motivation for using exception handling this way is that I can 
        //set the handler's message based on what part it failed at and the 
        //code associated with it, like below:

        sts = some_api_func2();

        if(sts != 0) { //An error occurred!
            if(errHandler) {
                ExceptionHandler handler("Error from func2",sts); //<--- Different err message
                *errHandler = handler; //<--- But does this cause a memory leak?
            }
            return false;
        }

        return true;
    }


//Main method

int main() {
    ExceptionHandler handler;

    if(!foo(&handler)) {

        std::cout << "An exception occurred: (" << handler.code() << ") " << handler.msg() << std::endl;

    } else {

        std::cout << "Success!" << std::endl;

    }


}
  • エラーが発生した場合、メソッド'foo()'はメモリリークを引き起こしますか?

  • もしそうなら、どうすればそれを修正できますか?そうでなければ、どうしてそうではないのですか?

  • これはエラーを処理する良い方法ですか?

前もって感謝します!

編集

上記のコードはメモリリークを生成しないことを学びましたが、次のコードがエラーを処理するためのより良い方法であることを学びました(皆さんありがとう!):

void foo() {

    int sts;

    sts = some_api_func1();


    if(sts != 0) 
        throw ExceptionHandler("Error at func1",sts);

    sts = some_api_func2();

    if(sts != 0)
        throw ExceptionHandler("Error at func2",sts);
}

int main() {

    try {
        foo();
        std::cout << "Success!";
    } catch(ExceptionHandler &e) { //<--- Catch by reference
        std::cout << "Exception: (" << e.code() << ") " << e.msg();
    }


}
4

1 に答える 1

1
ExceptionHandler handler;
if (!foo(&handler)) {
    //...
}

自動保存期間を持つオブジェクトを定義し、そのアドレスが関数に渡されfooます。ちなみに、関数に常に引数を渡すことがわかっている場合は、ポインターではなく参照によって引数を渡します。

bool foo(ExceptionHandler * errHandler = NULL) {
    ExceptionHandler handler("Error in foo", 1);
    *errHandler = handler;
}

また、自動保存期間を持つの別のインスタンスを作成するExceptionHandlerため、実行がスコープ外になると、このオブジェクトは破棄されます。ただし*errHandler = handler;、デフォルトの代入演算子を使用しているため、のデータメンバーの値をポイントするhandlerオブジェクトにコピーするので問題ありません。この場合、メモリリークは発生しません。errHandler

「これはエラーを処理するための良い方法ですか?」

いいえ。これはエラーを処理する適切な方法ではありません。代わりに例外を使用してください。プログラムを介してデータを渡す別の方法として、例外を悪用しないように注意してください。したがって、次も確認することをお勧めします。例外を保守的に使用する必要があるのはなぜですか。

その他の関連する質問:
例外をいつ使用すべきかについて、C ++コミュニティに一般的なコンセンサスがありますか?
「C++例外を使用しません」—代替手段は何ですか?クラッシュさせますか?


例外を使用することにした場合は、必ず値でスローし、参照でキャッチしてください

if (...)
    throw MyException(...);

そしてどこか:

try {
    ...
} catch (MyException& e) {
    ...
}
于 2013-02-28T22:43:19.823 に答える