2011-04-21 119 views
14

這是我的一個面試問題。處理構造函數的異常

令人驚訝的是,我從來沒有想過給自己一個這樣的問題。

我們可以在構造函數C++中有異常處理嗎?

現在時態並沒有多想我說「是的,我們可以做一個constructor.lets說我們正在使用new運算符分配一些內存到一個指針成員,它會拋出一個錯誤的alloc異常,這樣就有可能會有異常提出「

然後後來我認爲構造函數永遠不會返回一個值。那麼構造函數中的異常怎麼會被抓到。現在我問這個問題了!

有人能幫我擺脫這種困惑嗎?

+0

你會捕獲該異常調用代碼,而不是在構造函數中。 – helpermethod 2011-04-21 10:48:10

+3

異常不會以與返回值相同的方式返回,它們將堆棧跳到第一個適當的catch塊,因此儘管您無法從構造函數返回值,但可以從中引發異常。 – forsvarir 2011-04-21 10:50:30

+0

@Helper方法:如果您在構造函數中分配了內存,您肯定會想要在構造函數中捕獲異常,以便您可以取消分配內存(然後重新拋出)。但更智能的是讓對象只動態分配一個對象,所以你不需要執行這種手動清理。 – 2011-04-21 11:17:21

回答

12

看到這個GOTW Constructor Failures問題哪些地址您的查詢有點並繼續說這是浪費時間。

+3

+1我打算寫一個關於function-try-block的選項和它的許多缺陷,但我不會接近Sutter的描述:) – 2011-04-21 10:57:17

+0

這是一篇非常有趣的文章,def + 1 – Justin 2011-04-21 19:15:04

-2

C++具有類似於其他語言的try-catch子句。該教程可以在網上查到:http://www.cplusplus.com/doc/tutorial/exceptions/

編輯:例如變成完全的工作代碼

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    void f(){ 
    throw 10; 
    } 

    A(){ 
    try{ 
     f(); 
    } 
    catch(int e){ 
     cout << "Exception caught\n"; 
    } 
    } 
}; 

int main (int argc, const char * argv[]) 
{ 

    A a; 
    return 0; 
} 

這將產生輸出:

Exception caught 
+0

@ laas.i知道有很多documents.But我特別要求在構造函數中的異常處理。這並不代表我的問題。 – Vijay 2011-04-21 10:50:09

+0

C++沒有'finally'塊,並且C++中的異常處理在許多方面與Java等語言有所不同,例如對於清理,C++使用http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization – helpermethod 2011-04-21 10:53:14

+0

@Helper方法 - 你當然是對'finally'正確的,但據我瞭解,@ zombie詢問**構造函數內的異常處理**,所以我的示例仍然有效,或者應該糾正問題。我用更多的代碼更新我的答案。 – Laas 2011-04-21 11:27:45

2

構造函數沒有返回類型, 所以不可能使用返回碼 。 構造函數失敗的最好方法是因此給 拋出異常。如果你沒有 使用異常的選項, 「最不壞」的解決辦法是把 對象變成「殭屍」狀態由 設置內部狀態位使 對象的行爲有點像它的儘管它在技術上仍然 活着,但它仍然死亡。

你會趕上調用代碼例外,而不是在構造函數中。

查看How can I handle a constructor that fails?瞭解更多詳情(實際上,我建議閱讀關於異常處理的整個頁面,真正有啓發性)。

+0

我讀過這篇文章,但我期待人們在這種場景中使用的一些實用方法。 – Vijay 2011-04-21 10:51:31

+1

+1,但人們必須說這個問題也有點棘手。通常,當你以某種方式在構造函數中失敗時,它就會拋出一個構造函數,這完全可以在構造函數中嘗試/捕獲以處理其他失敗並避免構造函數首先失敗(或重新拋出)。根據情況,這可能是可取的。例如,如果在構造函數中構造兩個對象,並且第二個引發bad_alloc,那麼你會怎麼做?捕獲調用代碼中的異常將泄漏第一個對象。在構造函數內處理避免了這一點。 – Damon 2011-04-21 10:56:53

+0

@ zombie:有什麼場景?從構造函數中拋出異常?構造函數失敗?一個捕獲異常的構造函數? – forsvarir 2011-04-21 10:57:21

0

異常處理和返回類型完全不同。當程序在構造函數中發現異常時,它會通過catch塊[如果使用]或拋出調用方(main())將該異常拋出。在這種情況下,我們在構造函數和異常處理中都有catch塊。一旦處理異常,構造函數/函數中的其餘語句將開始執行。看下面的例子,

class A 
{ 
    public: 
    A(){ 
     printf("Hi Constructor of A\n");   
    try 
    { 
     throw 10; 
    } 
    catch(...) 
    { 
     printf("the String is unexpected one in constructor\n"); 
    } 
    printf("Hi Constructor of A\n"); 
} 
    ~A(){ 
    printf("Hi destructor of A\n"); 
} 
}; 

int main() 
{ 

try{ 
    A obj ; 
    throw "Bad allocation"; 
} 
catch(int i) 
{ 
    printf("the Exception if Integer is = %d\n", i); 
} 
catch(double i) 
{ 
    printf("the Exception if double is = %f\n", i); 
} 
catch(A *objE) 
{ 
    printf("the Exception if Object \n"); 
} 
catch(...) 
{ 
    printf("the Exception if character/string \n"); 
} 
printf("Code ends\n"); 
return 0; 
} 

這產生輸出:

Start: Constructor of A 
the String is unexpected one in constructor 
End: Constructor of A 
Hi destructor of A 
the Exception if character/string 
Code ends