ch4 – item 18: 使用 std::unique_ptr 於 exclusive-ownership (排他的-所有權) 資源管理
此筆記目前尚未整理完成,如需學習完整內容可參考隨附的 reference,或自行 google 搜尋
但因為作者要整理的筆記太多,如果想早點看到整理後的文章,可以下方留言「期待整理」之類的… 我會努力找時間優先整理!
std::unique_ptrs, raw pointers 有相同的 size,且大部分的功能都相同,
(包括 dereferencing, 簡單來說指使用「*」 ,例如 *var 取得值)
如果 raw pointers 能有效率的完成一件事情,那麼 std::unique_ptr 自然也是。
std::unique_ptr 介紹
std::unique_ptr 表現出「排他的 – 所有權」特徵,
當然這段是我直翻的,所以聽起來一定超怪,
總之 「std::unique_ptr 永遠擁有著他指向的 object ownership」,
因此,我們就可以討論一下的這些操作:
move
使用 move,假如從 source 移動到 destination,
會使得 destination 獲得這個 「object 的 ownership」,
這也同時造成 source 在進行這樣的操作後會變為 nullptr
copy
copy 對於 std::unique_ptr 是禁止操作的,
因為如果你可以 copy std::unique_ptr,
就會有兩個 std::unique_ptr 指向相同的 resource,
但「object 的 ownership」只能有一個, 這也顯示了他的排他性 (exclusive)。
delete
從上述我們可以推斷 std::unique_ptr 是個 move-only type,
當 std::unique_ptr 想要 delete resource 時,
預設 std::unique_ptr 的 delete 方式,
是已經被寫好的 raw pointer delete 內建在 std::unique_ptr 裡面
std::unique_ptr 使用情境
我們會常見 std::unique_ptr 使用於 factory function,
特別像是同一個物件會被多個物件所取用的情況,
例如:
class Investment{...}; // 投資
class Stock: // 股票
public Investment{...};
class Bond: //債券
public Investment{...};
class RealEstate: // 房產
public Investment{...};
像上面的這種情況,我們要使用的是「同一個」Investment,
這種時候 std::unique_ptr 就可以派上用場。
上面的例子不好懂的話,可以想像是你的「總財產」,
不管怎麼樣的消費,花費的都是你的「總財產」,
因此,不應該產生新的物件,讓「總財產」都是使用同一個物件。
另外 exclusive-ownership 的特性,也幫助了我們完成了這件「應該要唯一且排他」事情。
此外,像是這樣子的結構,我們其實會需要稍微思考一下要在哪裡 delete 這個資源
但因為 std::unique_pt 具有「唯一的 ownership」,
當 factory 被 destory 時,這個物件也會隨之自動的被 delete。
另外就像我們剛剛提到的,std::unique_ptr 具有可以被 move 的特性,
就算這個 std::unique_ptr 被任意的 move,
或是碰到 atypical (非典型的) control flow,例如:early function return, break
std::unique_ptr 也可以自動的判斷在合適的時間 destroy。
# Custom deleters
結論
- std::unique_ptr 是一個小, 快速, move-only 的 smart pointer,用來管理 resources 具有 exclusive-ownership 的特性
- 預設 std::unique_ptr 使用 delete 作為 resource destruction,但我們也可以自己設定 custom deleter,不過這樣的操作有可能使用的 std::unique_ptr size 變大。
- 從 std::unique_ptr 轉換至 std::shared_ptr 是非常容易的