2017-02-14 191 views
1

我有一個類可以在構造函數中拋出一個異常。我不知道自己的這個類的代碼,所以我不能改變這種行爲或者爲這個類添加其他實例化或初始化方法。我需要在main中創建這個類的一個對象。這是否意味着我需要有一個main(),其主要由一個巨大的try/catch塊這樣的:巨人嘗試在主要捕獲塊

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

,如果只能這樣主要是幾排長隊?這個try/catch塊很龐大。我覺得應該有一個更好的方式來做到這一點,但我想不出一個。

+8

「如果這主要是數千行長?」這將是你的問題,而不是try/catch塊。 –

+0

圍繞這種類型的代碼可能會失敗(並且不能被其他方式阻止),而不是整個事情。您不需要依靠巨大的try/catch來處理您的項目中可能發生的任何錯誤,這也可以捕獲意外的異常。 –

+1

[main()返回int] try-catch塊在main中是一個(接近普遍的)常見做法。 「......數千行......」是惡毒的。 – 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

這是否主要由一個巨大的try/catch塊

是的這是不是意味着我需要有一個main()。

如果這個主要是數千行長?

它不應該是。不要這樣做。將您的功能擴展到功能

並且不要忘記你的退貨類型爲main()(這是int)。

+0

將有興趣發現downvoter在此處不同意的內容。 –

0

如果您沒有明智的方法來處理異常,那麼請不要打擾try塊。只要讓例外逃脫並取消計劃 - 另一種選擇是在「世界」不健全時繼續 - 不是一個好主意。 當你沒有理智的方式來處理錯誤時,崩潰是合理的。捕捉異常是你應該只做,如果你有合理的方式來處理它們。默認情況下,讓它們傳播。

如果可以處理異常理智,加上try塊就在對象的實例,然後做理智的錯誤在catch塊處理

0

有可以處理這幾種不同的方式。

把一個function-try-block身體周圍的main()

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; 
} 

重構代碼,以大量的main()移動到另一個函數,您可以再try/except塊內撥打:

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; 
}