C++ set儲存指標(智慧指標)詳解

2020-07-16 10:04:30
如果改變物件,可能會改變 set 中物件指標的順序,所以指標的比較函數不能和物件有關。大多數時候,我們並不在意元素在 set 中的順序,而是在意容器中是否有這個元素。在這種情況下,就可以使用一個適用於指標但和它們所指向的元素無關的比較函數物件,推薦使用定義在 memory 標頭檔案中的 owner_less<T> 函數物件型別的範例來比較容器中的智慧指標。

owner_less<T> 模板為 shared_ptr 和 weak_ptr 物件定義了用於小於比較的函數物件型別。換句話說,允許 weak_ptr 物件和 shared_ptr 物件比較,反過來也可以,也允許和 weak_ptr 或 shared_ptr 物件比較。通過呼叫智慧指標的成員函數 owner_before() 實現了一個 owner_less<T> 範例,它提供了一個小於運算子,可以和另一個智慧指標進行比較。shared_ptr<T> 和 weak_ptr<T> 模板都定義了這個成員函數。

當這個智慧指標比引數傳入的智慧指標小時,owner_before<T>() 範例會返回 true,否則返回 false。比較基於智慧指標所擁有的物件地址,當兩個指標指向同一個物件時,說明這兩個指標等價。

在 shared_ptr<T> 類別範本中,定義 owner_before() 範例的函數模板的原型看起來如下所示:

template<typename X> bool owner_before(const std::sharedjptr<X>& other) const;
template<typename X> bool owner_before(const std::weak_ptr<X>& other) const;

weak_ptr<T> 類別範本定義了類似的成員。注意,這裡模板型別引數和類別範本的型別引數不同。這意味著可以比較指向相同型別物件的指標,也可以比較指向不同型別物件的指標。也就是說,shared_ptr<T1> 物件可以和 shared_ptr<T2> 物件或 weak_ptr<T2> 物件比較。這意味著指標所指向的物件可以和它所擁有的物件不同。

所有權對於 shared_ptr<T> 物件很重要。shared_ptr<T> 可以共用一個不屬於它的物件的所有權。換句話說,shared 指標所包含的地址並不是屬於它的物件的地址。這種 shared_ptr 的一種用途是指向一個它所擁有物件的成員,如圖 1 所示。


圖 1 兩個 shared 指標指向同一個物件的不同物件