2017-02-14 3 views
1

私はコンストラクタ内で例外をスローすることができるクラスを持っています。私はこのクラスのコードを所有しているので、この動作を変更したり、このクラスに他のインスタンス化または初期化メソッドを追加することはできません。私はメインの中にこのクラスのオブジェクトを作成する必要があります。このメインが長い行の数千人である場合はどうすればGiant Tryキャッチブロックのメイン

main() 
{ 
    try 
    { 
    A a; 
    ... 
    } 
    catch(std::exception& e) 
    { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

:これは私が()それは主にこのような1つの巨大なtry/catchブロックで構成され、メインを持っている必要があることを意味していますか?このtry/catchブロックは膨大です。私はこれを行うためのより良い方法があるべきであるように感じるが、私はそれを考えることができない。

+8

「このメインが何千もの行になる場合はどうなりますか?それはあなたの問題であり、try/catchブロックではありません。 –

+0

try/catchブロックで失敗する可能性がある(そうしないと予防できない)このタイプのコードを囲み、全体ではありません。プロジェクトで発生する可能性のあるエラーを処理するために巨大なtry/catchに頼る必要はありません。予期しない例外も同様に発生します。 –

+1

[main()はintを返します] mainのtry-catchブロックは(普遍的な)普遍的なプラクティスです。 "...数千行の長さ..."は悪質です。 – Loreto

答えて

4

このメインが何千もの行の場合はどうなりますか?
...私はこれを行うより良い方法があるように感じるが、私は考えることができない。明らかに悪いデザインのための兆候だとは、クラスや関数呼び出しにをリファクタリングする必要があります

main()でこのような何かに理想的

int main(int argc, char* argv[]) { 
    try { 
     Application app(argc,argv); 
     app.run(); 
    } 
    catch(std::exception& e) { 
     std::cout << e.what() << std::endl; 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
}  

それでも

try { 
    // Refactored 1000 lines of code 
} 
catch(std::exception& e) { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
} 

は、呼び出し元のコードを囲む必要があります。

+0

ああ。私は今参照してください。単一のエントリポイントを持つクラスにすべてをカプセル化することは、私がする必要があることです。 Application :: run()を持っている場所では、代わりに約1000行の条件テストと関数呼び出しがあります。しかし、それをすべて「アプリケーションマネージャ」クラスに入れて、何をやりとりする必要があるかを理解することが、私が必要としていたものです。これにより、単一の関数呼び出しが可能になり、main()を小さく簡潔に保ちます。ありがとう! –

3

これは私が1つの巨大なtry/catchブロック

はいのほとんどが構成されている)(メインを持っている必要があることを意味しています。

このメインに何千もの行がある場合はどうなりますか?

そうではありません。それをしないでください。あなたの機能を、うーん、の機能に変えてください!

main()(返品のタイプはint)を忘れないでください。

+0

ダウンボッターがここで同意しないことを発見することに興味があります。 –

0

例外を処理する賢明な方法がない場合は、tryブロックを気にしないでください。例外をエスケープしてプログラムを停止させてください。代わりに、 "世界"が正常な状態ではない間に続けるのが良い方法です。 エラーをうまく処理できないときにクラッシュすると合理的です。例外をキャッチすることは、の場合にのみ行うべきことです。に対処するには合理的な方法があります。デフォルトでは、それらを伝播させます。あなたは賢明例外を処理できる場合

は、単にオブジェクトのインスタンス化の周りtryブロックを追加してcatchブロックでの取り扱い正気のエラーを行う

0

あなたがこれを扱うことができるいくつかの異なる方法があります。 。

main()の体の周りfunction-try-blockを置く:

int main() try 
{ 
    A a; 
    // use 'a' as needed ... 
    return EXIT_SUCCESS; 
} 
catch (const std::exception& e) 
{ 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
} 

リファクタリングあなたがtry/exceptブロック内で呼び出すことができます別の関数にmain()の大部分を移動するためのコード:

個人的に
void run() 
{ 
    A a; 
    // use 'a' as needed ... 
} 

int main() 
{ 
    try 
    { 
    run(); 
    return EXIT_SUCCESS; 
    } 
    catch (const std::exception& e) 
    { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
    } 
} 

をスタック上ではなく、ヒープ上でクラスをインスタンス化するだけです。このようにして、try/catchをインスタンシエーションの周りに置くことができます。

#include <memory> 

int main() 
{ 
    std::unique_ptr<A> a; // or std::auto_ptr<A> prior to C++11... 

    try 
    { 
    a.reset(new A); 
    // or, in C++14 and later: 
    // a = std::make_unique<A>(); 
    } 
    catch(const std::exception& e) 
    { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
    } 

    // use 'a' as needed ... 

    // the A object is freed automatically when 'a' goes out of scope... 

    return EXIT_SUCCESS; 
}