2009-06-01 77 views
3

什麼是從C++函數返回成功或一個或多個錯誤代碼的好方法?如何從C++函數返回多個錯誤代碼

我有這個成員函數調用save(),它保存到每個成員變量,至少有10個這些成員變量被保存到,爲了調用save(),我想查找如果調用失敗了,如果是的話,哪個成員變量(一些是硬故障,一些是軟的)。

+0

爲什麼你需要提供多個錯誤代碼?也許如果你給我們提供關於這樣一個函數的使用模式的更多信息,多錯誤代碼的原因,或者什麼都沒有,那麼或許有人對你有更好的解決方案。 – 2009-06-01 21:44:05

+0

我有這個成員函數調用save(),它保存到每個成員變量,至少有十個這些成員變量被保存到,爲了調用save(),我想知道是否調用失敗,如果是這樣,在哪個成員變量(一些是硬故障,一些是軟的)。 – bob 2009-06-01 21:49:37

回答

7

您可以返回具有多個錯誤字段的對象,也可以使用'out'parameters。

你是如何做到這一點取決於你的設計,你究竟是什麼試圖返回。常見的情況是,您需要報告狀態代碼以及各種消息。這有時會在函數返回狀態碼作爲返回值,然後通過'out'參數返回消息狀態。

如果您只是返回一組'代碼',那麼構建一個結構類型並返回它可能會更有意義。在那種情況下,我傾向於將它作爲out參數傳入,並讓該方法在內部更新它,而不是每次都分配一個新參數。

你打算這樣做一次還是多次?

+0

一個對象是一個很好的解決方案,因爲你可以返回任何你想要的東西,例如錯誤代碼,錯誤字符串等。 – 2009-06-01 21:45:17

4

返回兩個值的最簡單方法是使用的std ::對<>模板:

2

你需要將它們返回作爲輸出參數:

bool function(int& error1, int& error2, stringx& errorText, int& error3); 
2

我會用一個bitset如果你」重新意圖是純粹返回錯誤狀態。例如

const bitset<10> a_not_set(1); 
const bitset<10> b_not_set(2); 
const bitset<10> c_not_set(4); 

... 

bitset<10> foo(T& a, T& b, T& c, ...) 
{ 

    bitset<10> error_code = 0; 

    ... 


    if (/* a can't be set */) 
    { 
     error_code |= a_not_set; 
    } 

    ... 

    if (/* b can't be set */) 
    { 
     error_code |= b_not_set; 
    } 

    ... 

    // etc etc 

    return error_code; 
} 

bitset<10> err = foo(a, b, c, ...); 
if (err && a_not_set) 
{ 
    // Blah. 
} 
+0

體積小巧,但不易讀。 – 2009-06-01 21:45:07

2

您可以對位操作(又名標誌)使用整數。

+0

體積小巧但不易讀。 – 2009-06-01 21:45:12

+0

你很明顯會使用#define ... – 2009-06-01 21:59:16

7

我知道這並沒有真正回答你的問題,但是...

在C++中,你應該使用異常,而不是返回錯誤代碼。錯誤代碼最常用於不想強制庫用戶使用特定錯誤處理約定的庫,但在C++中,我們已經有了stdexcept。當然,可能有一些原因不會使用異常,例如,如果您正在編寫嵌入式代碼或內核擴展。

0

我不熟悉項目的內部和約束條件,但如果可能的話,嘗試使用異常而不是錯誤代碼。

的原因列here, at C++ FAQ lite,和他們訂立:

所以比起錯誤通過返回碼報告,如果使用的try/catch /拋出可能會導致有較少的錯誤代碼,開發成本更低,並且上市時間更快。

6

我通常使用一個boost::tuple

typedef boost::tuple<int,int> return_value; 

return_value r = my_function(); 

int first_value = boost::get<0>(r); 
int second_valud = boost::get<1>(r); 

編輯

您還可以使用boost::tie從元組提取值:

boost::tie(first_value, second_value) = r; 
2

我可能會嘗試拋出異常第一,但它取決於你的編碼範例。請檢查一些關於C++異常處理可能更好的原因的書籍或文章。

如果我真的需要堅持retrun錯誤代碼的風格,我會定義一個eunm類型指定與位操作錯誤..

enum error 
{ 
    NO_ERROR = 0, 

    MEMBER_0_NOT_SAVED = 1, 
    MEMBER_1_NOT_SAVED = 1 << 1, 
    MEMBER_2_NOT_SAVED = 1 << 2, 
    // etc.. 

}; 

int save() 
{ 
    int ret = NO_ERROR; 

    // fail to save member_0 
    ret |= MEMBER_0_NOT_SAVED; 

    // fail to save member_1 
    ret |= MEMBER_1_NOT_SAVED; 

    // .... 

    return ret; 
} 

int main(void) 
{ 
    int ret = save(); 
    if(ret == NO_ERROR) 
    { 
     // good. 
    } 
    else 
    { 
     if(ret & MEMBER_0_NOT_SAVED) 
     { 
       // do something 
     } 

     if(ret & MEMBER_1_NOT_SAVED) 
     { 
       // do something 
     } 

     // check the other errors... 
    } 
} 

這只是一個粗略的例子。最好把它放到一個類中或者使用一個名字空間。