智慧型指標的實現原理
智慧型指示通常是通過引用計數器來自動維護物件的引用情況。引用計數跟蹤該類有多少個物件共享同一指標。每次通過adoptref
函式建立智慧型指標時將引用計數置為
1;當物件被另乙個智慧型指標引用時增加與之相應的引用計數;對智慧型指標進行賦值時,賦值操作符減少左運算元所指物件的引用計數(如果引用計數為減至
0,則刪除物件),並增加右運算元所指物件的引用計數;呼叫析構函式時,析構函式減少引用計數(如果引用計數減至
0,則刪除基礎物件)。
參考原始碼
refptr.h
passrefptr.h
三種指標
raw pointers
原始指標,即普通指標,相對智慧型指標而言。
refptr
webkit中帶有引用計數器的智慧型指標。
passrefptr
主要用在函式的引數或者函式的返回值,用於減少refptr
在傳遞的時候會有額外的引用計數消耗。
webkit
中的passrefptr
指標在命名時通常加上
"prp"
字首。
三種指標之間的轉換
raw pointers——
>passrefptr
passrefptrprppoint = adoptref(new node);
passrefptr——
>refptr
passrefptrprppoint = adoptref(new node);
refptrpoint= prppoint ;
refptr——
>passrefptr
passrefptrprppoint = point.release();
refptr——
>raw pointers
1) 從refptr
或者passrefptr
中獲取原始指標
point.get()
或者prppoint.get()
2) 銷毀原來的引用指標,將其轉換為原始指標point.release().leakref()
或者prppoint.leakref()。
三種指標使用小結
本地變數
如果指標的生命週期是確定的,本地變數可以使用原始指標。
如果本地變數需要維持對該物件的引用並確定它的生命週期,本地變數需要使用refptr
本地變數不應該使用passrefptr
。成員變數
如果指標的生命週期是確定的,成員變數可以使用原始指標。
如果該類需要維持對該物件的引用並確定它的生命週期,成員變數應該使用refptr
成員變數不應該使用passrefptr
。函式引數
如果函式不需要維持對該物件的引用,函式引數可以是原始指標。
如何函式需要維持對該物件的引用,函式引數應該是passrefptr
。這種情況常見於大部分
setter
函式中。除非函式很簡單,一般在該函式開始處應該將
passrefptr
轉換成refptr
。函式返回值
如果函式的返回結果是乙個物件,但是物件的所有關係沒有被轉移,返回結果應該是乙個原始指標。這種情況常見於大部分getter
函式中。
如果乙個函式的返回結果是乙個新物件或者物件的所有關係發生轉移,返回的結果應該是乙個passrefptr
。新物件
新物件應該在一建立的時候就立即轉化為refptr
指標,以便智慧型指標能夠自動地對所有引用進行計數。
物件refcounted
類的物件,上面的過程需要用
adoptref
方法轉化。
好的使用智慧型指標的習慣應該是將類的建構函式定義為私有函式,並且定義乙個共有的create
函式用於建立類物件並且返回乙個
passrefptr
指標。
WebKit中的智慧型指標
前幾天看了下webkit裡的幾種常用的智慧型指標 小結一下 refcounted 提供引用計數器功能。使用時繼承之 class foo public refcounted 為了更為方便安全地使用引用計數功能,webkit提供了refptr。threadsafeshared 多執行緒版本的引用計數 r...
智慧型指標類模板(中) Qt中的智慧型指標
qt中的智慧型指標 qpointer 當其指向的物件被銷毀時,它會被自動置空 析構時不會自動銷毀所指向的物件 qsharedpointer 引用計數型智慧型指標 可以被自由的拷貝和賦值 當引用計數為0時才刪除指向的物件 include include using namespace std clas...
智慧型指標類模板(中) Qt中的智慧型指標
qt中的智慧型指標 qpointer 當其指向的物件被銷毀時,它會被自動置空 析構時不會自動銷毀所指向的物件 qsharedpointer 引用計數型智慧型指標 可以被自由的拷貝和賦值 當引用計數為0時才刪除指向的物件 include include using namespace std clas...