2013-05-17 192 views
2

我讀的C++的一些注意事項和遇到下列問題就來了構造函數和異常

問:一個構造函數可以拋出異常?構造函數失敗時如何處理錯誤?

答:構造函數永遠不會引發錯誤。

現在這個答案有點困惑我,只是爲了確保我去了online並且讀到你總是可以從構造函數中拋出異常。我只是想確定這樣做是否會在筆記中出現錯字,並且我可能不會錯過重要的東西。

+2

鑑於'new'可以拋出,我會說你的「A」是錯誤的。 – DavidO

+0

也許這意味着「構造函數不能返回錯誤,所以通知構造錯誤的慣用方式是拋出異常」...... – juanchopanza

回答

4

這些註釋是錯誤的,如果他們談論的是一般的構造函數。 Ctors確實可以正常投擲。也許那是在討論一個保證非伸縮建築的特定類?

另一方面,強烈建議您編碼,這樣您的析構函數永遠不會拋出。他們這樣做是合法的,但在堆棧展開期間拋出異常會導致程序立即終止(致電std::terminate)。

4

當然,它可以。即使標準容器(例如std::vector)也會從構造函數中拋出std::bad_alloc。這個FAQ說的是實話。

+2

您鏈接到與OP相同的常見問題解答。 :) – DavidO

+0

@DavidO \t大聲笑,我明顯需要重述一下這個答案:) – fasked

1

您可以從構造函數中拋出異常,但要小心:如果對象構造不當,析構函數將不會被調用。

class Foo 
{ 
public: 
    Foo(int i) 
    { 
     throw i; 
    } 

    ~Foo() 
    { 
     std::cout << "~Foo()" << std::endl; 
    } 
}; 

int main() 
{ 
    try 
    { 
     Foo f(42); 
    } 
    catch(...) 
    { 
     std::cout << "Catched" << std::endl; 
    } 

    return 0; 
} 

輸出:

Catched 

爲了解決這個問題,你應該封裝一個構造到另一個:

Foo() 
{ 

} 

Foo(int i): Foo() 
{ 
    throw i; 
} 

輸出:

~Foo() 
Catched 
+0

儘管析構函數沒有執行,但在第一個例子中沒有內存泄漏。 (用valgrind觀察) – stefan

+0

從來沒有沒有捕捉所有的條款沒有(重新)拋出或你會有一個不好的時間。 – 2013-05-17 16:08:28

+0

@stefan,即使valgrind不顯示內存泄漏,在第一種情況下內存將被泄漏。 – soon