首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

函數返回值設計藝術:何時用返回值、何時用輸出參數

     編輯:關於C語言

前言

「函數該用返回值還是輸出參數?」是困擾許多開發者的設計決策。本文從代碼審查實戰出發,對比「返回值直接攜帶結果」與「輸出參數承載結果、返回值表達狀態」兩種風格,總結判斷依據與最佳實踐。

案例一:獲取對象屬性 —— 傾向返回值

// 風格 A:輸出參數(原作者習慣)
void GetExtent(Extent &out) { out = m_extent; }

// 風格 B:直接返回(審查者建議)
Extent& GetExtent() { return m_extent; }

優勢 B:

  • 調用鏈式表達:`auto e = obj1.GetExtent() + obj2.GetExtent();`
  • 無需預先定義變量,減少一行代碼與作用域汙染。
  • 符合「查詢操作不修改狀態」的語義(Command-Query Separation)。

適用場景**:獲取器、純計算、無失敗可能、結果為值語義類型(小對象、支援移動語義)。

案例二:查找操作可能失敗 —— 傾向輸出參數 + 狀態返回

// 原設計:返回對象,失敗拋異常/返回哨兵
Property SearchProperty(string name) {
    for (auto &p : props) if (p.name == name) return p;
    throw "not found";  // 或返回 static Property invalid;
}

// 改進:bool + 輸出參數
bool SearchProperty(const string &name, Property &out) {
    for (auto &p : props) if (p.name == name) { out = p; return true; }
    return false;
}

優勢**:

  • 調用者**必須**處理失敗情況(`if (Search(...))`),編譯器不會忽略返回值。
  • 避免異常開銷(嵌入式/實時系統常禁用異常)。
  • 語義明確:「嘗試獲取,成功則填充 out」。

決策流程圖

需要表達「操作是否成功/值是否存在」?
  ├─ 否 → 直接返回結果值(支援鏈式、移動語義)
  └─ 是 → 返回 bool/錯誤碼/optional,結果通過輸出參數/返回值承載
           ├─ C++17+ → 推薦 std::optional 統一語義
           ├─ C++11-14 → bool + T& out / 錯誤碼 enum + T& out
           └─ C / 老代碼 → int 錯誤碼 + T* out

現代 C++ 最佳實踐:`std::optional` (C++17)

#include <optional>
#include <string>
#include <vector>

struct Property { std::string name; int value; };

class Registry {
    std::vector<Property> props;
public:
    // 查找:可能不存在
    std::optional<Property> find(const std::string &name) const {
        for (auto &p : props) if (p.name == name) return p;
        return std::nullopt;
    }

    // 純獲取:必定存在(前置條件)
    const Property& get(const std::string &name) const {
        for (auto &p : props) if (p.name == name) return p;
        throw std::out_of_range("Property not found"); // 契約違反
    }
};

// 調用
if (auto opt = reg.find("foo"); opt) {
    use(*opt);  // 解包
} else {
    handle_missing();
}

總結檢查清單

場景推薦形式關鍵理由
純查詢、必定成功返回值 (引用/值)鏈式調用、CQS 原則
查詢、可能失敗`std::optional` / `bool + T&`強制處理失敗、無異常開銷
修改狀態、需報錯錯誤碼 enum / `std::expected` (C++23)豐富錯誤語義、可擴展
多返回值`std::tuple` / `struct` / `std::pair`類型安全、結構化綁定
C 語言介面`int err_code, T* out`ABI 穩定、跨語言調用

核心原則

「返回值表達『主要結果』,輸出參數表達『附帶產出』;若主要結果可能不存在,將『存在性』提升為返回值主體,主要結果轉為附帶產出。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved