vtk智能指针->对智能指针的理解和使用

我就是我 2022-06-04 00:11 539阅读 0赞

学习代码:

  1. #include <vtkSmartPointer.h>
  2. #include <vtkBMPReader.h>
  3. #include <vtkImageData.h>
  4. #include <vtkObject.h>
  5. // MyFunction函数:演示智能指针可以作为函数返回值
  6. vtkSmartPointer<vtkImageData> MyFunction()
  7. {
  8. vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
  9. std::cout<<"MyFunction::myObject reference count = "<<myObject->GetReferenceCount()<<std::endl;
  10. return myObject;
  11. }
  12. //测试文件:data/VTK-logo.bmp
  13. int main(int argc, char* argv[])
  14. {
  15. //演示引用计数:
  16. vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
  17. reader->SetFileName("C:\\Users\\Administrator\\Desktop\\vtk1\\Examples\\Examples\\Chap02\\data\\VTK-logo.bmp");
  18. reader->Update();
  19. std::cout<<"Reference Count of reader->GetOutput (Before Assignment) = "
  20. <<reader->GetOutput()->GetReferenceCount()<<std::endl;
  21. vtkSmartPointer<vtkImageData> image1 = reader->GetOutput();
  22. std::cout<<"Reference Count of reader->GetOutput (Assign to image1) = "
  23. <<reader->GetOutput()->GetReferenceCount()<<std::endl;
  24. std::cout<<"Reference Count of image1 = "
  25. <<image1->GetReferenceCount()<<std::endl;
  26. vtkSmartPointer<vtkImageData> image2 = reader->GetOutput();
  27. std::cout<<"Reference Count of reader->GetOutput (Assign to image2) = "
  28. <<reader->GetOutput()->GetReferenceCount()<<std::endl;
  29. std::cout<<"Reference Count of image2 = "
  30. <<image2->GetReferenceCount()<<std::endl;
  31. //////////////////////////////////////////////////////////////////////////
  32. //////////////////////////////////////////////////////////////////////////
  33. //演示智能指针可以作为函数返回值
  34. //由于函数MyFunction()的返回值是通过拷贝的方式,
  35. //将数据赋予调用的变量,因此该数据的引用计数保持不变
  36. std::cout<<"myObject reference count = "
  37. <<MyFunction()->GetReferenceCount()<<std::endl;
  38. vtkSmartPointer<vtkImageData> MyImageData = MyFunction();
  39. std::cout<<"MyFunction return value reference count = "
  40. <<MyFunction()->GetReferenceCount()<<std::endl;
  41. std::cout<<"MyImageData reference count = "
  42. <<MyImageData->GetReferenceCount()<<std::endl;
  43. //////////////////////////////////////////////////////////////////////////
  44. //////////////////////////////////////////////////////////////////////////
  45. //如果没有给对象分配内存,仍然可以使用智能指针:
  46. vtkSmartPointer<vtkBMPReader> Reader = vtkSmartPointer<vtkBMPReader>::New();
  47. vtkImageData* pd = Reader->GetOutput();
  48. //////////////////////////////////////////////////////////////////////////
  49. system("pause");
  50. return EXIT_SUCCESS;
  51. }

引用计数概念:

引用计数是一个简单 的垃圾回收机制。
只要其他对象引用某对象,这个对象的引用计数就会增加1,当最后所有引用该对象的对象都移除之后,这个对象自动析构。
在vtk当中这样的好处是可以实现数据的共享而不用复制,可以节省内存。

  1. image1->GetReferenceCount();//该方法可以获得当前对象的引用计数

一旦某个对象的引用计数等于0,就表明没有别的对象再引用他了,他的使命也就结束了,程序会自动析构这个对象。

智能指针:

智能指针可以自动管理引用计数的增加和减少,若检测到某对象的引用计数减少为0,则会自动释放给对象的资源。
这又要回到vtk中创建对象的方式上了:
vtk有两种创建对象的方式:

  1. 使用vtkObjectBase里的静态成员函数New(),再用Delete()方法析构。
  2. 使用智能指针的方式vtkSmartPointer < T >的方式。

对于第一种方式创建的对象是程序员再堆上创建的对象,这个对象并不会自动析构,不关编译器的事情(编译器只管栈上的事情),所以在程序的最后必须调用Delete()方法,使得引用计数减一。

  1. vtkBMPReader* reader = vtkBMPReader::New();
  2. ....
  3. reader->Delete();//这里并没有直接析构这个对象,而是使引用计数减一。

对于第二种方式,不用手动调用Delete()方法,因为引用计数的减少和增加都是智能指针自动完成的。
使用智能指针就需要包含智能指针的头文件vtkSmartPointer.h。vtkSmartPointer是一个模板类所需要的参数就是待创建的对象的类名。
必须写成一下形式:

  1. vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();

不能写成:

  1. vtkSmartPointer<vtkBMPReader> reader = vtkBMPReader::New();

这样编译没问题,但是程序退出的时候智能指针无法自动释放该对象的内存。出现内存泄漏。
所以不能把对象的原始指针赋值给智能指针。

关于智能指针的介绍可以看下面这篇文章:https://www.cnblogs.com/TenosDoIt/p/3456704.html

发表评论

表情:
评论列表 (有 0 条评论,539人围观)

还没有评论,来说两句吧...

相关阅读

    相关 智能指针

    RAII(Resource Acquisition Is Initialization): 资源分配即初始化,定义封装一个类,用来实现调用构造函数时就可完成资源的分

    相关 理解C++智能指针

    C++智能指针是面试中经常会问到的一个经典知识点,本身使用也具有很大的意义。本文从下面三个方面对智能指针的内容进行整理,以期对智能指针能够有一个较为清晰的认识: 1 智能指

    相关 智能指针

    在C++中,如果指针使用不当,比如没有及时释放指针所指向的内存,或者野指针等,会造成系统发生不可预估的错误,为了防止这一情况的发生,C++ STL提供了一系列智能指针类型 智

    相关 智能指针

    智能指针 在java中如果在堆上开辟内存是不需要手动释放的,我们叫做智能指针;但是在C++中如果用new在堆上开辟了空间,我们需要用delete进行手动释放,否则造