gb 智能指針

 
在Gamebryo中通過使用智能指針實現引用計數的半自動化。這通過NiPointer來實現,這個模板類重載了操作符,使得它的實例表現出來像一個標準的指針。然而,
智能指針自動地增加和減少它指向對象的引用計數,從而應用程序不在直接調用NiRefOjbect的引用計數函數。例如在函數中如果聲明一個局部智能指針變量並指向對象A,那麼對象A的引用技術在賦值的時候將會增加1。當函數返回的時候,這個局部的智能指針被摧毀(超出了作用域),對象A 的引用計數將會減少1。
約定俗成,每個從NiRefObject派生的Gameroy類都有一個方便的智能指針聲明,它表現在類型名稱上加“Ptr”(NiNodePtr、NiTriShapePtr等)。

NiNodePtr spParent = <some node>;

NiNodePtr spChild = NiNew NiNode; 
//spChild points to new object. Reference count is 1.

spParent->AttachChild(spChild); 
//Reference count of object pointed to by spChild is now 2, since NiNode objects use smart pointers to refer their children.
 
spParent->DetachChild(spChild); 
//Reference count of object pointed to by spChild decreases  to 1.
 
spChild = 0; 
//Reference count of object decreases to 0. Object is deleted.
做爲NiRefObject 派生類對象的應用程序指針在交叉調用會減少某個對象智能指針引用計數的時候,這個對象也應該是個智能指針。例如,如果你從父節點中detach一個NiAVObject子對象時,但不想對象在被父結點detach的時候刪除,那麼你的代碼中指向子對象的指針也應當是個智能指針。
 
永遠不要對智能指針作delete調用,這一點非常重要。這是標準堆上的指針對象和智能指針對象的唯一的行爲區別。在智能指針對象上調用delete操作,
那麼不論這個智能指針指向的指針對象的引用計數是多少,該對象都會被刪除。如果想釋放一個智能指針對指向對象的引用(在智能指針因超出作用域被摧毀之前),將智能指針賦值爲0即可這樣確保對象引用計數減少到0的時候摧毀,類似的永遠不要對一個NiRefObject對象指針作delete操作,這將也會永久摧毀這個對象。
 
正如在NiRefObject中討論的那樣,智能指針智能指向在堆上動態分配的對象。永遠不要將智能指針指向一個在棧上的對象(局部變量)。永遠不要將智能指針指向一個靜態的對象。

爲了區別指針和智能指針,Gamebryo對常規指針使用“pk”前綴,對智能指針使用“sp”前綴
 
如果一個函數使用智能指針作爲參數,那麼不要把一個沒有被其他智能指針引用的對象常規指針作爲參數傳入到函數中。如果這樣做,那麼這個對象指針將會被摧毀掉。接下來是這個問題詳細描述:
    1 常規指針pkObject指向一個動態分配的對象,其引用計數爲0。
    2 傳輸pkObject到一個智能指針參數,編譯器隱式調用智能指針的構造函數將pkObject轉換到一個臨時的智能指針,並將對象的引用計數增加到1。
    3 在函數調用的作用域,這個臨時智能指針通過調用智能指針的拷貝構造函數複製到一個局部智能指針中,並將對象的引用計數增加到2。
    4 當函數調用返回的時候,局部智能指針被摧毀,並將對象的引用計數減少到1。
    5 在調用完成的時候,臨時智能指針對象也被摧毀,並將對象的引用計數減少到0,這導致對象被釋放掉。
當處理引用計數對象的時候智能指針不是必須的,智能指針是一種簡易的工具。NiRefObject包含IncRefCount函數和DecRefCount,可以直接通過這些函數添加和釋放引用。智能系統是這些調用的一個簡單包裝。應用程序可以混合使用智能指針和手工修改引用計數。
智能指針系統提供了兩個宏,一個永遠定義智能指針類型另一個用來智能指針類型轉換。類型定義的宏是NiSmartPointer(classname)。例子如下
NiSmartPointer(NiNode)
類型轉換宏是NiSmartPointerCast(classname, pkObject)。如下是典型的使用:
NiAVObjectPtr spChild = <some pointer known to be an NiNode>;
NiNodePtr spNode = NiSmartPointerCast(NiNode, spChild);
注意類型轉換時操作是靜態的不是動態的,所以我們應當在知道要轉換的指針是正確的類型的時候使用NiSmartPointerCast
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章