weak_ptr智能指針

爲什麼需要weak_ptr?

因爲雖然我們可以使用shared_ptr指針,但是不得不說使用shared_ptr還有一些不美好的地方需要注意和解決,所以我們的weak_ptr也是爲了幫助解決這些問題而設計出來的。

問題如下:

  1. 環向指向:兩個共享指針之間互相指向,所以就永遠也不會出現計數器減爲0的情況出現所以,就不會釋放資源。
  2. 想共享但是不願意擁有:比如說引用的壽命其實比引用的對象存活時間長,所以shared_ptr也不可能釋放對象,一般的指針判斷不出來它們指向的對象已經失效

weak_ptr指針的特點

允許共享但是不擁有對象, 這個class會建立起一個shared pointer,一旦最末的一個該對象的shared pointer失去了所有權,所有的weak ptr都會自動成空,因而,在default和copy函數以外class weak_ptr只提供“接受一個shared_ptr”的構造函數。

不能使用*或者->來訪問weak_ptr裏面的所指向的對象,而是必須建立起另外一個shared pointer,這樣設計的原因:

  1. 在weak_ptr之外建立一個shared_ptr這樣可以檢驗weak_ptr裏面存的指針還有沒有效,如果沒有就會拋出異常或者建立一個empty shared pointer
  2. 當指向的對象正在被處理的時候,shared pointer無法被釋放
  3. weak只是提供小批量操作,只夠創建、複製、賦值weak ptr以及轉換爲shared pointer

使用的一個例子

class Person{
public:
    string name;
    shared_ptr<Person> mom;
    shared_ptr<Person> dad;
    vector<shared_ptr<Person> > kids;
    Person(string myName,
           shared_ptr<Person> &mother,
           shared_ptr<Person> &father):
           name(myName),mom(mother),dad(father){}
};

仔細觀察上面的這個Person類,裏面不僅有兩個父親母親的shared_ptr同時每個父母都要記錄自己的孩子,放在vector裏面保存一份,最後就是一個循環,一個Person希望釋放自己的shared_ptr但是,在它的父母類裏面保存了一份在vector裏面,如果要釋放父母的話,也不允許,因爲保存了一份在子類裏面。所以修改方式就是將vector元素類型改成weak_ptr就可以解決這個問題。

想要確定weak_ptr背後的對象是否存活?

  1. 調用expired(),它會在weak_ptr不在共享對象時返回true,這等同於檢查use_count()是否爲0,但速度較快
  2. 可以使用相應的shared_ptr構造函數明確將weak_ptr轉換爲一個shared_ptr,如果被指對象已經不存在,該構造函數會拋出一個bad_weak_ptr異常。
  3. 調用use_count()則會詢問使用的對象的數量,如果返回0表示不存在任何有效的對象,通常只應爲調試而使用,use_count效率不總是很高 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章