Open Scene Graph 記憶體管理

2021-05-24 04:47:04 字數 1314 閱讀 7322

在osg中有乙個類被使用的最多,那就是ref_ptr.osg中提供了一種自動管理記憶體的機制,這種機制涉及到兩個類:第乙個就是ref_ptr,另外乙個就是osg::referenced.

osg::reference支援通過引用計數的方式來控制自己的生命週期,它期望,每次被乙個新客戶引用的時候,新客戶能給他新增引用計數;而當客戶不需要再使用它的時候,希望客戶能夠減少引用計數.

如果引用計數達到0,那麼osg::reference就會析構自己,釋放記憶體.

但是這個過程對客戶要求比較高,誰能記得住每次都新增引用和減少引用呢? ref_ptr能!這也是它為什麼存在的原因.ref_ptr過載了大量的操作符來實現這個新增引用和減少引用的過程.

下面是乙個使用ref_ptr的基本原則:

1.如果希望用ref_ptr來管理記憶體,你的類需要繼承osg::referenced

2.如果你的類的物件想要持有乙個osg::referenced的派生類的指標,你應該持有乙個ref_ptr然後,讓ref_ptr來持有乙個指標

3.如果你只是在乙個函式中短時間的使用乙個osg::referenced的派生類的指標,你不需要使用ref_ptr,直接用就可以了.如果你在短時間使用後,會傳遞給其他的物件來持有這個指標,你也不需要用ref_ptr,因為通過ref_ptr來長時間持有這個物件是其他的物件的責任了.

4.如果有兩個類都從osg::referenced派生,而你想繼承這兩個類,那就有麻煩了。osg中的派生都沒有用virtual修飾符,所以你的類物件中會出現兩份osg::referenced的東西.ref_ptr實際上不知道該怎麼處理了.如果是乙個嚴格的編譯器,編譯器甚至會報錯!.這個時候,你必須做出選擇,從其中乙個派生,而另乙個則採用組合的方式來處理.多繼承就是這一點不好.不過話說回來,在**中應該盡量不使用多繼承,除非是從完全沒有成員的純抽象類繼承(純抽象類當做介面用).

下面來一段ref_ptr的**看看:

inline ref_ptr& operator = (t* ptr)

在給ref_ptr賦值的時候,它首先把新物件給ref一下,然後把原來的物件給unref一下.這個持續比較重要,如果反過來寫就不行了.你想想看,如果我把同乙個指標給它兩次,如果反過來寫,物件就會被銷毀了! 然後是referenced的**:

inline void referenced::ref() const

else

#endif

}inline void referenced::unref() const

else

#endif

if (needdelete)

}

去掉多執行緒控制的**,其原理是很好理解的.

OpenSceneGraph學習筆記

源 在檔案release 1600 gdal mapserver src.zip之中,將源 解壓即可。這裡我們只需要解壓壓縮包release 1600 gdal mapserver src.zip中的gdal資料夾。將解壓的資料夾命名為gdal 20130222。解壓結果如圖所示 用microsof...

Qt窗體嵌入OpenSceneGraph

然後再新增add subdirectory osgviewerqt 這樣編譯出了很多問題,檢視了其他部落格的做法,說是要配置cmake中需要的qt路徑,但是依然報錯,只能先放著以後解決了。pro檔案內容 qt core qt gui qt opengl sources main.cpp libs l...

內點法python 內點法

文字理解 內點法屬於約束優化演算法。約束優化演算法的基本思想是 通過引入效用函式的方法將約束優化問題轉換成無約束問題,再利用優化迭代過程不斷地更新效用函式,以使得演算法收斂。內點法 罰函式法的一種 的主要思想是 在可行域的邊界築起一道很高的 圍牆 當迭代點靠近邊界時,目標函式徒然增大,以示懲罰,阻止...