日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VTK修炼之道80:VTK开发基础_智能指针与引用计数

發(fā)布時(shí)間:2025/3/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VTK修炼之道80:VTK开发基础_智能指针与引用计数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.引用計(jì)數(shù)

VTK經(jīng)過多年的開發(fā)與維護(hù),已經(jīng)形成了一套穩(wěn)定的框架和開發(fā)規(guī)則。因此,了解這些規(guī)則和框架是定制VTK類的基礎(chǔ),這其中用到了大量面向?qū)ο蟮脑O(shè)計(jì)模式,例如對象工程模式、觀察者/命令模式;還有就是當(dāng)下非常流行的引用計(jì)數(shù)與智能指針等高級內(nèi)存管理等。
內(nèi)存管理在大型的工程中是非常重要的內(nèi)容,如果不能有效地管理內(nèi)存,將嚴(yán)重影響到應(yīng)用程序的執(zhí)行效率,甚至可能造成程序崩潰。之前學(xué)習(xí)C++基礎(chǔ)時(shí),教材中都會反復(fù)的強(qiáng)調(diào),使用new操作符申請的空間,一定要使用delete來釋放。C++中并沒有提供高級的內(nèi)存管理與垃圾回收機(jī)制,通常進(jìn)行手動管理。這對于簡單的程序而言可以輕松完成,但是對于大型程序就會疲于應(yīng)付。最有代表性例子就是,當(dāng)一個(gè)內(nèi)存塊(可以看做一個(gè)指針)被多個(gè)對象引用時(shí),刪除任意一個(gè)對象,都可能影響其他對象,引用計(jì)數(shù)和智能指針剛好用來解決這個(gè)問題。

1.1 引用計(jì)數(shù)

簡單來說,引用計(jì)數(shù)就是每個(gè)對象中維護(hù)一個(gè)引用計(jì)數(shù)的變量,表示當(dāng)前對象被多少對象引用。

當(dāng)一個(gè)對象被另一個(gè)對象引用時(shí),該對象的引用計(jì)數(shù)就會加1;當(dāng)一個(gè)對象取消對該對象的引用時(shí),該對象的引用計(jì)數(shù)減1.當(dāng)引用計(jì)數(shù)為0時(shí),程序就會撤銷該對象。

VTK中實(shí)現(xiàn)引用計(jì)數(shù)的類為vtkObjectBase。VTK是一個(gè)C++類庫,在VTK中,C++的繼承與多態(tài)得到了完美的體現(xiàn)。經(jīng)過十幾年的發(fā)展,所有的VTK類集合可以看做一個(gè)樹狀結(jié)構(gòu),vtkObjectBase則是他們共同的祖先。

這也說明了絕大部分VTK類都支持引用計(jì)數(shù)。vtkObjectBase中定義了一個(gè)ReferenceCount變量,改變量記錄了引用計(jì)數(shù)。當(dāng)一個(gè)vtkObjectBase及其子類對象創(chuàng)建時(shí),ReferenceCount就會被初始化為1。

vtkObjectBase::vtkObjectBase {this->ReferenceCount = 1; }在該類中,vtkObjectBase的構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)以及“=”操作符都被聲明為“protected”類型,因此不能顯示地構(gòu)造和銷毀vtkObjectBase及其子類對象。vtkObjectBase定義了一個(gè)靜態(tài)函數(shù)New(),用于生成vtkObjectBase對象。New()函數(shù)中調(diào)用了構(gòu)造函數(shù)來生成一個(gè)對象,并在構(gòu)造函數(shù)中初始化引用計(jì)數(shù)為1.

1.2?Register()函數(shù)以及Unregister()函數(shù)實(shí)現(xiàn)計(jì)數(shù)

生成一個(gè)vtkObjectBase及其子類對象后,該對象并不會孤立地存在,多數(shù)情況下又可能被其他對象引用。這是需要調(diào)用Regester()函數(shù)實(shí)現(xiàn)引用計(jì)數(shù)加1;Register()函數(shù)中有一個(gè)vtkObjectBase*類型的形參,代表引用當(dāng)前對象的其他對象的類型(可以設(shè)置為NULL)。因此,引用計(jì)數(shù)關(guān)心的是被引用的數(shù)量,而不關(guān)心引用者是誰。而Unregister()函數(shù)實(shí)現(xiàn)引用計(jì)數(shù)減1,并檢查引用計(jì)數(shù)的數(shù)量。當(dāng)引用計(jì)數(shù)為零時(shí),自動銷毀該對象。

1.3?Delete()函數(shù)刪除對象釋放內(nèi)存

對于New()的對象,一定要通過Delete()對象來刪除。Delete()函數(shù)并非直接刪除對象,而式調(diào)用Unregister()對象將引用計(jì)數(shù)減1,如果引用計(jì)數(shù)為0,則調(diào)用析構(gòu)函數(shù)來刪除對象。

一個(gè)簡單的實(shí)例如下:

vtkCamera* camera = vtkCamera::New(); //引用計(jì)數(shù)為1 renderer->SetActiveCamera(camera); //引用計(jì)數(shù)為2 renderer->Delete(); //引用計(jì)數(shù)是1 camera->Delete(); //camera被刪除首先調(diào)用vtkCamera::New()函數(shù)實(shí)例化一個(gè)vtkCamera對象camera,此時(shí)camera的引用計(jì)數(shù)初始化為1.然后將camera通過SetActiveCamera()函數(shù)傳遞至一個(gè)vtkRenderer對象renderer中。
vtkRenderer::SetActiveCamera()函數(shù)的代碼如下:
void vtkRenderer::SetActiveCamera(vtkCamera* cam) {if(this->ActiveCamera == cam){return;}if(this->ActiveCamera){this->ActiveCamera->UnRegister(this);this->ActiveCamera = NULL;}if( cam ){cam->Register( this );}this-<ActiveCamera == cam;this->Modified();this->InvokeEvent(vtkCommand::ActiveCameraEvent, cam); }解釋:
vtkRenderer中定義了一個(gè)vtkCamera對象ActiveCamera。SetActiveCamera()函數(shù)用于設(shè)置該對象的值。在調(diào)用SetActiveCamera()函數(shù)時(shí),如果當(dāng)前已經(jīng)設(shè)置了ActiveCamera,則先UnRegister()該對象,并將其指向NULL。然后,調(diào)用Register()函數(shù)增加一個(gè)引用,說明camera在renderer中被應(yīng)用,并將ActiveCamera指向camera。此時(shí),camera的引用計(jì)數(shù)數(shù)目為2(如果這里又有一個(gè)新的vtkCamera對象通過SetActiveCamera設(shè)置,同樣先將此前設(shè)置的camera對象引用計(jì)數(shù)減1,再賦值)。而當(dāng)執(zhí)行renderer->Delete()函數(shù)時(shí),由于renderer的引用計(jì)數(shù)為1,所以renderer會被銷毀,而此時(shí)camera又變?yōu)榱?.當(dāng)執(zhí)行camera->Delete()后,其引用計(jì)數(shù)減一,此時(shí)camera計(jì)數(shù)為零,刪除camera對象。

1.4 引用計(jì)數(shù)的先天缺陷

其實(shí),引用計(jì)數(shù)并不是十分的完美。本身就有先天的缺陷——對循環(huán)引用無能為力。即無法處理對象之間相互引用形成一個(gè)環(huán)路的情況,例如,VTK中vtkAlgrthm和vtkExecute對象之間。

2.智能指針

智能指針可以完全避免內(nèi)存泄漏問題。

2.1 智能指針

VTK中智能指針類為vtkSmartPointer。VTKSmartPointer是一個(gè)模板類,繼承自VTKSmartPointerBase類。VTKSmartPointerBase中定義了一個(gè)vtkObjectBase類型的指針對象Object,用于存儲智能指針中實(shí)際生成的對象。智能指針定義為:

vtkSmartPoint<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New(); //引用計(jì)數(shù)為1VTKSmartPointer中定義了靜態(tài)函數(shù)New()來生成一個(gè)智能指針對象。
該函數(shù)的核心在于:會根據(jù)模板參數(shù)類型來生成一個(gè)對象,并將其保存在基類VTKSmartPointerBase的成員變量Object中。

  • VTKSmartPointer中重載了“->”操作符
返回實(shí)際模板參數(shù)類型的對象,因此可以方便地訪問對象的成員函數(shù),如camera->setFocusPosition(0,0,0)。
  • VTKSmartPointer重載了“=”操作符
可以在VTKSmartPointer對象之間進(jìn)行賦值。在賦值過程中,VTKSmartPointer會自動控制其內(nèi)部對象指針Object的引用計(jì)數(shù)加1.

例如:

vktSmartPointer<vtkCamera> camera1 =vtkSmartPointer<vtkCamera>::New(); vtkSmartPointer<vtkCamera> camera2 = camera1;需要注意的是,此時(shí)camera1和camera2的引用計(jì)數(shù)都等于2。
過程為:首先camera1的vtkCamera對象Object調(diào)用Register()函數(shù),自動將引用計(jì)數(shù)加1,談后將camera2的Object指向camera1的Object對象。

2.2 智能指針釋放內(nèi)存

當(dāng)一個(gè)智能指針對象的生命周期結(jié)束時(shí),會自動調(diào)用其析構(gòu)函數(shù)釋放內(nèi)存。在析構(gòu)函數(shù)中會調(diào)用其內(nèi)部對象Object的UnRegister()函數(shù)修改引用計(jì)數(shù)。如果此時(shí)的引用計(jì)數(shù)為0,Object對象會自動釋放內(nèi)存。

3. vtkObjectBase中的幾個(gè)重要函數(shù)

3.1 GetClassName()

該函數(shù)用于返回當(dāng)前類的名字。其通過調(diào)用類內(nèi)保護(hù)類型的虛函數(shù)GetClassNameInternal()來實(shí)現(xiàn)。vtkObjectBase時(shí)VTK中絕大對數(shù)類的基類,因此這些類都可以訪問GetClassName()函數(shù)來獲取類名。我們必須在這子類中覆蓋GetClassNameInternal()函數(shù),這樣才會有“多態(tài)性”效應(yīng)。

3.2 IsTypeOf/IsA()

IsTypeOf()是一個(gè)靜態(tài)函數(shù),其參數(shù)為一個(gè)char類型字符串,通常為一個(gè)類的名字,用于判斷一個(gè)類名是否為vtkObjectBase。

虛函數(shù)IsA()則調(diào)用IsTypeOf()來判斷一個(gè)對象的類型。vtkObjectBase的類中都覆蓋了IsA(),以便判斷實(shí)際的類型。

3.3 Print()/PrintSelf()/PrintHeader()/PrintTrailer()

Print()用于輸出類的成員變量和狀態(tài),其內(nèi)部調(diào)用PrintSelf()/PrintHeader()/PrintTrailer()三個(gè)虛函數(shù)。

4. 常用vtkObjectBase子類及其繼承關(guān)系


  • vtkCommand主要涉及觀察者/命令模式的實(shí)現(xiàn)。
  • vtkInformationKey與vtkInformation搭配使用,用于實(shí)現(xiàn)VTK的執(zhí)行管線。
  • vtkObject是一個(gè)非常非常重要的基類!!其子類包括vtkAlgrithm和vtkExecutive兩個(gè)實(shí)現(xiàn)Filter類最重要的類;而vtkDataObject是VTK中所有數(shù)據(jù)結(jié)構(gòu)類如:vtkPolyData、vtkImageData等的基類。

5.參看資料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發(fā)進(jìn)階[M]. 機(jī)械工業(yè)出版社, 2015.

總結(jié)

以上是生活随笔為你收集整理的VTK修炼之道80:VTK开发基础_智能指针与引用计数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。