iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
自我挑戰組

Effective C++ 讀書筆記系列 第 25

[Day 25] Make interfaces easy to use correctly and hard to use incorrectly (2)

  • 分享至 

  • xImage
  •  

前言

今天,我們接續昨天介紹的守則,繼續來看看更具體 "Make interfaces easy to use correctly and hard to use incorrectly" 的實例跟介紹吧!

好的設計─以return shared_ptr的function為例

接續昨天最後我們有提到一致性很重要,這樣可以讓user了解之後就都依一樣的使用方式,反之,如果使用起來有很多前提或特殊的使用方式,就會讓user容易忘記這些複雜的規則,進而用錯。以以下這個factory function為例,它return的是一個動態分配的物件:

Investment* createInvestment();

而它return出來的東西需要記得去delete,才不會有memory leak。這就是一種 "額外的規則",使用上容易會有兩個潛在危機: 1. delete失敗 2. 重複delete同一個pointer。要避免這個問題,如同前面[Day 19] Use objects to manage resource有提到的,我們可以用smart pointer來管理這個資源,但user也可能會忘記放到smart pointer裡面。所以在這個例子中,好的設計的例子就是直接讓這個factor function return的就是一個smart pointer:

std::shared_ptr<Investment> createInvestment();

這樣就消滅了user錯用─忘記delete等等的情形。
同時,我們也可以把正確的delete行為都顧到─例如假使它的資源清理行為應該是getRidOfInvestment,也可以把deleter寫進去,避免user用錯清理方式,例如:

std::shared_ptr<Investment> createInvestment()
{
    std::shared_ptr<Investment> retVal(new Investment, getRidOfInvestment);
    ...
    return retVal;
}

另外,這同時也可以避免 "cross-DLL 問題"
所謂的 cross-DLL 問題會發生在其中一個DLL使用用new來產生的物件,但在其他DLL裡面被delete,細節可以參考其他參考資料,簡而言之,shared_ptr可以避免此問題,因為它會在同一個DLL中去delete,這樣這個createInvestment產出的return就可以在不同DLL中被安全的使用。

今天講了這麼多shared_ptr,但重點其實不是在介紹shared_ptr的用法,而是說明我們考量到user可能會犯的錯,而採用shared_ptr是一種可以避免各種可能錯誤的設計。當然使用shared_ptr也是有代價的,例如它比raw pointer更耗空間,也比較慢,但相比之下它可以避免的錯誤價值更大。

總結

貼心重點提醒:

  • Good interfaces are easy to use correctly and hard to use incorrectly. You should strive for these characteristics in all your interfaces.
  • Ways to facilitate correct use include consistency in interfaces and behavioral compatibility with built-in types.
  • Ways to prevent errors include creating new types, restricting operations on types, constraining object values, and eliminating client resource management responsibilities.
  • shared_ptr supports custom deleters. This prevents the cross-DLL problem, can be used to automatically unlock mutexes, etc.

這個守則的要點真多XD 再整理一下要點的要點─首先就是將這個大原則銘記在心,正確好用!2是一致性,最好跟built-in type性質都一樣,3是一些設計方式包含用new types並限制它的值域,並把資源管理都設計掉。最後則是可以藉助shared_ptr來避免掉一些常見errors。

參考資料


上一篇
[Day 24] Make interfaces easy to use correctly and hard to use incorrectly (1)
下一篇
[Day 26] Treat class design as type design
系列文
Effective C++ 讀書筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言