2017-08-11 35 views
0

我想從構造函數返回錯誤代碼,因爲構造函數 沒有返回錯誤代碼,我試圖在構造函數 上發生異常。然後在catch塊中返回我的適當的錯誤代碼。 這是從構造函數返回錯誤代碼的正確方法嗎?如何從構造函數返回錯誤代碼?

#include <exception> 
#include <iostream> 

class A { 
public: 
    A() { throw std::runtime_error("failed to construct"); } 
}; 

int main() { 
    try { 
    A a; 
    } catch (const std::exception& e) { 
    std::cout << "returining error 1 \n"; 
    return 1; 
    } 

    return 0; 
} 
+1

對我來說,將構造函數設爲noexcept是一個好習慣...... 也許,一種很好的方法可以將狀態置於類似下面的對象:invalid。 我正在尋找更好的答案 –

+3

只需在整個使用例外。錯誤返回值具有所有問題,特別是它們太容易被忽略。 –

+3

是的,構造函數應該構造一個有效的對象或拋出異常。 – VTT

回答

0

有沒有辦法做到這一點。最好的方法可能是有一個靜態的init()方法,它將返回類的一個實例並使構造函數保持私有狀態。您可以從init方法中完成大部分構造,並且只從中返回錯誤代碼。

+0

不幸的是,init()方法不適用於許多類,特別是那些具有帶構造函數的參數的成員變量。 –

+0

不是說我同意了答案,但該記錄的初始化函數可以採取完全轉發可變參數模板參數 – lapinozz

+0

@lapinozz的init()函數,與任何參數,必須在構造函數體中調用,所以不能初始化什麼 - 它只能分配。 –

7

根據isocpp.org,來處理在C++構造失敗的合適的方法是:

拋出異常。

由於構造函數沒有返回類型,所以不可能使用錯誤代碼。 但是:

如果你沒有使用異常的選項,「最不壞」的解決辦法是通過設置一個內部狀態位,以使對象的行爲,使對象變成「殭屍」狀態有點像死了,即使它在技術上還活着。

但你真的應該使用異常,如果你能在信號構造故障,說:

在實踐中,「殭屍」的事情變得很醜陋。當然,你應該比殭屍對象更喜歡異常,但是如果你沒有使用異常的選項,殭屍對象可能是「最不好的」選擇。

0

取決於您認爲這樣的錯誤的可能性以及進一步程序執行的正確初始化有多關鍵。

  • 如果未初始化對象被認爲是特例(例如因爲內存不足),則會拋出異常。
  • 如果它是一個預期的失敗,你想在這裏和現在處理,將對象設置爲失敗/默認構造狀態,並允許用戶查詢錯誤代碼(例如,當std::fstream不能夠打開一個文件)。如果要使用不同的參數值重試對象初始化,這特別有用。

順便說一句:如果你決定使用異常,我可能不會把它變成一個錯誤代碼,除非你絕對必須。特殊設計的例外情況,使您不必手動傳遞錯誤代碼。

+0

您不能重試對象初始化,至少不在同一個對象上。 –

+0

案例2的缺點是您現在必須測試「您是否已正確初始化?」每次在使用該對象之前。成爲一個真正的無賴。 – user4581301

+0

@NeilButterworth:也許不是標準意義上的,但我說的是初始化成有用的狀態(例如,如果你考慮的農場,你可以先嚐試使用用戶提供的文件名來構建它,如果失敗,則可能需要回退到默認文件,您可以使用open訪問) – MikeMB