跳轉至內容

更多 C++ 慣用法/資源返回

來自華夏公益教科書

資源返回

[編輯 | 編輯原始碼]

在工廠函式的返回型別中明確地傳達資源所有權的轉移。

工廠函式通常用於建立新的資源並將其返回給呼叫方。新的資源可以是原始記憶體、動態分配的物件、資料庫遊標/連線、鎖等等。關於資源的一個重要問題是,誰擁有資源,誰釋放資源?很多時候,介面都是以呼叫方隱式負責資源釋放的方式開發的。如果呼叫方沒有意識到這一點,或者只是忘記了採取正確的步驟,就會導致一種易於錯誤使用的介面。以下程式碼片段展示了一個例子。

struct X
{
  void foo() {}
};
X * Xfactory() // Resource ownership implicitly transferred to the caller.
{
  return new X; // Dynamically allocated instance
}
int main (void)
{
  Xfactory()->foo(); // Dynamically allocated instance of X leaks here
}

資源返回慣用法提供了不同的替代方案來糾正這種情況,並導致(某種程度上)難以錯誤使用的介面。

解決方案和示例程式碼

[編輯 | 編輯原始碼]

解決方案是將資源封裝在一個資源管理智慧指標中,並返回智慧指標而不是原始指標。最簡單的資源返回慣用法形式在下面的程式碼片段中顯示。

struct X
{
  void foo() {}
};
std::unique_ptr<X> Xfactory() // Resource ownership explicitly transferred to the caller.
{
  return std::unique_ptr<X> (new X); // Dynamically allocated instance
}
int main (void)
{
  Xfactory()->foo(); // Dynamically allocated instance of X does not leak here
}

在確定要使用的資源管理智慧指標型別以返回資源時,需要考慮幾個問題。可能的選擇是

  • std::auto_ptr
  • boost::shared_ptr / std::shared_ptr(從 C++11 開始)
  • C++0x 中的 std::unique_ptr
  • 使用者定義的 控制代碼/體 慣用法

Scott Meyers 在他的文章 The Resource Return Problem 中對選擇一種而不是另一種的優缺點進行了詳細的討論。只要不需要自定義刪除功能(除了普通的舊 delete),auto_ptr 是一種快速使用資源返回慣用法的方式,如上所示。auto_ptr 提供了資源的獨佔但可轉移的所有權,這僅僅透過檢視介面就變得非常清楚。對於動態分配的指標返回工廠函式,boost::shared_ptr 也是一個不錯的選擇,因為它提供了正常的複製語義(例如,它可以儲存在 STL 容器中)。它還允許將資源釋放策略從正常的刪除操作更改為自定義刪除,而不會影響客戶端。

在資源返回慣用法涉及獨佔所有權的情況下,移動建構函式 慣用法在轉移資源所有權時經常很有用。

已知用途

[編輯 | 編輯原始碼]
[編輯 | 編輯原始碼]

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書