一.作用:共享類時,用于标記類被共享的次數。每被一個類共享, rc++ ;每有一個類結束共享, rc-- ;當 rc=0 時,被共享的類才被銷毀。這避免了:
1. 某類已無共享,但仍留在記憶體中。
2. 某類仍被其他類共享,卻被提前銷毀。
模型, render state 均可被共享。
一般通過智能指針來管理 rc 。
Object 類的兩個内容: 1 。 Run time type information;( 用于存儲類的類型 )
2. reference counter. ( rc 變量及遞增遞減 rc 的函數)
記憶體洩露追蹤系統: object 類中存在一個 static 成員 hash-map* InUse ,它用于追蹤遊戲系統存在的類,遊戲初始化時,該 hash_map 為空,遊戲進行時, hash_map 會 相應變化,遊戲結束時, hash_map 應當為空,若不為空,則會由 static 函數 PrintInUse 輸出,便于程式員處理記憶體洩露。
二. 智能指針便是基于上述記憶體洩露追蹤系統建立的:
1. 智能指針是模闆類, template<class T> 該指針指向被共享的類 T ,智能指針的唯一 private 成員變量時指向被共享的類的一般指針。
2. Sp 的 constructor 會将 rc++ (每當為 T 聲明一個 sp ,即是引用了一次), destructor 會将 rc-- (原理同上)
3. 指派操作符的重載中,在調用 rc++ , rc— 之前,會比較指派雙方是否相等,這是為了:
(1) 防止自我指派。
(2) 防止意外的自我銷毀。(先 ++ 為 1 ,後 — 為 0 ,檢測到 0 立即自我銷毀)
4. Implict conversions 的作用有二:
(1) 使 sp 看起來似乎 支援了多态性(說明: node 基于 spatial ,是以 spatialptr* a=Nodeptr* b; 合法。然而, NodePtr 并非基于 SpatialPtr ,兩者均為 Pointer 類的模闆産物。)但是由于 implict conversions ,我們可以多态性。(代碼見 p806 )
(2) 支援了 sp 是否為 null 的判斷。(通過重載 bool 轉換符實作)
三, 智能指針在使用過程中應注意的問題。
1. 智能指針本身無需 new ,聲明一個即可。注意: sp 完成使命後一定要指派為 0 。(類似于一般指針。)
2. Sp 隻能指向動态配置設定記憶體的對象。
3. 将智能指針用作函數參數和傳回值時應高度謹慎 !!!
問題的根源在于函數将參數傳入時會執行一次 constructor ,(建立本地副本),函數結束時會進行一次 destructor 。什麼沒做,一次 con~ ,一次 des~ , rc — >1 — >0, 會造成被共享類的銷毀。
傳回值同理。
解決辦法是:使實參類型或接受傳回值的變量類型也為 sp ,即避免類型轉換。(因為在聲明實參或接受傳回值的變量時 rc 已經 +1 ,不會出現為 0 的情況。)