2015-09-10 101 views
1

我有一個類foo(我不能修改)白衣只有一個構造函數,有一個參數是這樣的:Catch構造函數拋出錯誤?

foo bar("Hello!"); 

由於構造函數可以拋出一個錯誤,我想要實現的錯誤處理。我第一次嘗試是這樣的:

try { 
    foo bar("Hello!"); 
} 
catch { 
    cerr << "Something went horribly wrong..."; 
    return -1; 
} 

不過,現在footry塊的範圍內,並且不能用於其他地方。如果我理解正確的話,我不能聲明對象而不初始化它,所以我可以在try塊之外聲明bar。那麼我該怎麼做來捕獲構造函數拋出的錯誤呢?

編輯:澄清,這是在我的main,並在catch我將中止程序。此外,參數是一個將被打開的文件,所以沒有已知的安全輸入永遠不會引發異常。

+4

將所有相關的代碼放在try塊中。或者在try塊中調用的函數中。 – juanchopanza

+0

與相關的代碼,你的意思是使用該對象的代碼?這意味着我的大部分計劃。似乎只是爲了捕捉可能僅在初始化期間發生的錯誤? – Anders

+1

那麼,你的程序大部分都可以包含在'main()'函數中,對吧?那麼爲什麼不把它包含在你放入try塊的另一個函數中呢? – juanchopanza

回答

3

的問題是相當簡單:構造函數失敗了,所以從來沒有創建bar對象。 C++強制執行此操作,並阻止您在此情況下使用bar

您可能會以另一種方式解決這個問題:

foo makeFoo() 
{ 
    try { 
    return foo("Hello!"); // May throw 
    } 
    catch(...) { 
    return foo("Safe"); // We know that "Safe" will not throw. 
    } 
} 

bar foo{makeFoo()}; 

如果你想,如果拋出異常退出程序,你可以打印一個錯誤信息,並調用exit(EXIT_FAILURE)漁獲內。

+1

感謝您的回答!恐怕沒有已知的輸入是完全安全的,因爲參數是要讀取的文件。我認爲在C++中沒有'null'或類似的東西,我可以返回? – Anders

+1

@Anders:對象不能爲空。但指針可以是'nullptr'。這裏有'boost :: optional '這可能會或者可能不會持有'foo'。如果你的基本文件丟失,你當然可以打印一條錯誤消息,並在catch中調用'exit(EXIT_FAILURE)'。 – MSalters

+0

不知道'退出'。這解決了我的問題。謝謝! – Anders

2

你可以使用堆分配:

foo *p = 0; 
try { 
    p = new foo("parm"); 
} catch(const Error& err) { 
    ... 
} 
foo& instance = *p; 
// Here you can use instance normally... 

delete p; // destroy before leaving scope (or use a smart pointer) 
+1

這會讓你得到一個空指針解引用。另外,爲什麼不'std :: unique_ptr'? – MSalters

+0

@MSalters:我假設在catch內部,他會解決這個問題,要麼分配一個工作對象,要麼只是放棄程序,不要在沒有工作對象的情況下超出範圍。使用「或使用智能指針」正是我正在考慮的... – 6502

+0

這是在我的'main'中,並在'catch'我只打印一個錯誤消息和'return'。 – Anders