簡體   English   中英

函數返回類型:指針,參考或其他?

[英]Function Return Type: Pointer, Reference or something else?

讓我們假設我總是需要函數的direkt返回類型為錯誤代碼(計算成功或失敗),然后我將返回一些參數作為參數。 將它們定義為引用(並在空前創建它們)或更好地返回指針是否更好?

編輯:我應該更精確:錯誤代碼是強制性的,因為我必須堅持給出的編碼指南。

可能性A:

ErrorCode func( some_parameters ... , ReturnType & result)
...
ReturnType result; // empty constructor, probably not good practice
func( some_parameters ..., result)

可能性B:

ErrorCode func( some_parameters ... , ReturnType * result){
    ...
    result =  new ReturnType(...)
    ...
}
...
ReturnType * result; // void pointer
func( some_parameters ..., result)
...
delete result; // this is needed if I do not use a smart pointer

更好的是:也許你有更合適的解決方案?

編輯:請說明你正在使用哪個標准,因為不幸(指南)我必須堅持使用C ++ 98。

我會做以下(一般來說)

1.)拋出異常而不是返回錯誤代碼

如果這是不可能的(出於任何原因)

2.)直接返回指針(raw或std :: unique_ptr)並返回nullptr失敗

如果返回類型必須是bool或者沒有返回所有對象(指針/堆已分配)

3.)返回你的錯誤代碼(bool或enum類)並接受所有要初始化的對象的引用參數(必須有對象可以說)和指向可以選擇創建/初始化的對象的指針

如果無法在調用之前創建對象(例如,因為它不是默認構造)

4.)傳遞對指針(raw或std :: unique_ptr)的引用或指向指針的指針,然后由函數填充

如果您只有一個true / false返回碼,則std :: optional(或類似)可能是一個選項。

我不喜歡返回std :: pair或std :: tuple,因為如果你必須開始使用.first / .second或std :: get <>()來訪問你的不同返回類型,它會讓你的代碼看起來很煩人。 使用std :: tie()可以減少這一點,但它(但是)使用起來並不舒服,並且可以防止使用const。

例子:

std::unique_ptr<MyClass> func1() { /* ... */ throw MyException("..."); }

std::unique_ptr<MyClass> func2() { /* ... */ }

ErrorCode func3(MyClass& obj, std::string* info = nullptr) { /* ... */ }

ErrorCode func4(std::unique_ptr<MyClass>& obj) { /* ... */ }

int main()
{
     try 
     {
          auto myObj1 = func1();
          // use ...
     }
     catch(const MyException& e)
     {
          // handle error ...
     }

     if(auto myObj2 = func2())
     {
          // use ...
     }

     MyClass myObj3;
     std::string info;
     ErrorCode error = func3(myObj3, &info);
     if(error == ErrorCode::NoError)
     {
          // use ...
     }

     std::unique_ptr<MyClass> myObj4;
     ErrorCode error = func4(myObj4);
     if(error == ErrorCode::NoError)
     {
          // use ...
     }
 }

編輯:一般情況下建議保持API的一致性,所以如果你已經有一個中型或大型代碼庫,那么你應該堅持使用一種或另一種策略(如果你沒有充分的理由不這樣做) 。

這是std::optional的典型示例。 可悲的是它還沒有,所以你想使用boost::optional

這假設結果總是“成功結果”或“失敗沒有結果”。 如果您的結果代碼更復雜,您可以返回
std::pair<ResultCode, std::optional<ReturnType>>

對所有返回信息使用返回值是一種好方法。 例如:

std::tuple<bool, ReturnType> func(input_args....)

或者,如果狀態代碼是布爾值,則返回類型可以是std::optional (或其前綴),其中一個空的optional表示函數失敗。

但是,如果計算通常成功,並且只在極少數情況下失敗,那么返回ReturnType會更好,並拋出異常以指示失敗。

當代碼沒有對每個返回值進行錯誤檢查時,代碼更容易閱讀; 但要成為健壯的代碼,需要在某處或其他地方檢查這些錯誤。 例外情況可讓您在一個地方處理各種異常情況。

不知道它是否適用於你的情況,但如果你只有兩個狀態返回類型,那么可能只是從你的函數返回指針然后測試它是否為nullptr?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM