在 C++11
中的標準模板庫(STL,為了要解決記憶體洩漏問題(Memory Leak) 的問題,便引進了Smart Pointer來更方便管理記憶體,而標頭檔案為 <memory>
Smart pointers enable automatic, exception-safe, object lifetime management.
cppreference
如果在 free
跟 delete
前程式碼就爆開了,當記憶體空間沒有釋放到一定程度就會爆開
嚴格上來說智慧指標是由模板類別來進行實作,可以參考
std::unique_ptr
unique_ptr
是一種smart pointer,並且確保 unique_ptr
的所指向的物件只會被一個智慧指標進行管理,當超出作用域時變自動進行銷毀
C++11
,使用 std::unique_ptr<T> ptr(new T(...));
C++14
,使用 std::make_unique<T>(Args&& ... args)
unique_ptr
進行賦值動作,在編譯時期就會出錯!,原因是因為在其模板函數的實作中,已經將賦值的operator禁用了unique_ptr
的ownership,就需要使用std::move
,移動完成後本來的aInst
就會是空指標std::shared_ptr
shared_ptr
是一種可以共享同一個資源的智慧指標,內部會記錄這份資源被使用的次數 (Reference Counter) ,只要還有 shared_ptr
指向的物件存在時、資源就不會釋放;只有當所有使用這份資源的 shared_ptr 物件都消失的時候,資源才會被自動釋放
C++11
,使用 std::shared_ptr<T> ptr(new T(...));
C++14
,使用 std::make_shared<T>(Args&& ... args)
std::weak_ptr
搭配 shared_ptr
使用的smart pointer,和 shared_ptr
的不同點在於 weak_ptr
不會影響資源被使用的次數,也就是說的 weak_ptr
存在與否不代表資源會不會被釋放掉,而 weak_ptr
只是用來檢測記憶體是否正確被釋放
a->b
= (*a).b
(*ptr)
and ptr.get()
經由動態配置的物件或函數都會一個管理者,負責在物件不再需要的時候將物件刪除,而所有權是可以共享的,也就是可以將物件或函數傳遞到下一個管理者,而最後一個管理者要負責將物件刪除,也就是物件或函數創建與刪除,是有可能在不同管理者之間執行的,造成管理記憶體的難處
如果需要動態配置的話,儘可能把所有權保持在配置記憶體的那段程式碼中。如果其他地方也需要存取該物件的話,考慮複製一份物件,或是傳遞物件的指標 (Raw Pointer) 或 reference &
方式,不要傳遞所有權。如要真的要轉移所有權 (Ownership) 最好使用 std::unique_ptr
明確表達所有權的轉移
以狀態設計模式為例,我們可以透過 Context
管理各個狀態所需要的資源,並藉由原始指標 (raw pointer) 方式傳入到 State
當中,讓各個從 State
衍生出的類別,可以使用這些資源,這樣便提供了類似一個工具包的角色,並讓不同人去取用,同時也可以傳遞狀態間的資源或資料轉移