一、引用计数
每个对象中都会维护一个引用计数的变量,用来表示当前对象被多少对象引用。当对象被另一个对象引用时,引用计数加1;当另一个对象取消对该对象的引用或者另一个对象被移除时,引用计数减1。如果对象的引用计数减为0时,程序会自动析构这个对象。
二、智能指针
智能指针是自动管理资源的工具,可以在对象不再被使用时自动释放所占用的内存,可以避免内存泄漏的问题。
智能指针会自动管理引用计数的增加和减少,如果检测到某个对象的引用计数减为0,就会自动释放该对象的资源,从而达到自动管理内存的目的。
三、vtkSmartPointer
1.使用
在VTK中使用智能指针用类vtkSmartPointer来定义对象。
vtkSmartPoint<T> point = vtkSmartPoint<T>::New();
例如:
vtkSmartPoint<vtkCamera> camara = vtkSmartPoint<vtkCamera>::New();
在vtkSmartPoint对象之间进行赋值,vtkSmartPoint会自动控制内部对象的引用计数加1。
vtkSmartPoint<vtkCamera> camera = vtkSmartPoint<vtkCamera>::New();
vtkSmartPoint<vtkCamera> camera1 = camera;
此时, camera和camera1的引用计数都为2。
2.获取引用计数
可以通过vtkObjectBase类中GetReferenceCount()方法获取指针的引用计数,其中vtkObjectBase为VTK绝大多数的基类。
3.内存释放
当一个智能指针对象的生命周期结束时,会自动调用其析构函数释放内存。在析构函数中会其修改引用计数。如果此时的引用计数为0,该对象会自动释放内存。
四、注意
如果不用智能指针,直接用New()创建对象,最后一定要调用Delete()方法,该方法使其引用计数减1。如果不调Delete(),可能会出现内存泄漏的问题。
五、测试
widget.h
vtkSmartPointer<vtkRenderer> renderer;//渲染器
vtkSmartPointer<vtkPoints> points;
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QFileDialog>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
renderer = vtkSmartPointer<vtkRenderer>::New();
qDebug()<<"a renderer refrtence count:"<<renderer->GetReferenceCount();
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renwindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renwindow->AddRenderer(renderer);
ui->vtk_widget->SetRenderWindow(renwindow.Get());
qDebug()<<"b renderer refrtence count:"<<renderer->GetReferenceCount();
points = vtkSmartPointer<vtkPoints>::New();
qDebug()<<"aaa points refrtence count:"<<points->GetReferenceCount();
test_points = vtkPoints::New();
qDebug()<<"a test_points refrtence count:"<<test_points->GetReferenceCount();
//演员
actor = vtkSmartPointer<vtkActor>::New();
qDebug()<<"aaaaa actor refrtence count:"<<actor->GetReferenceCount();
renderer->AddActor(actor);
qDebug()<<"bbbbb actor refrtence count:"<<actor->GetReferenceCount();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_2_clicked()
{
qDebug()<<"---------------------------------------------";
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
if(fileName == "") return;
pcl::io::loadPCDFile(fileName.toStdString(),*cloud);
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
for (int i = 0; i<cloud->size(); i++)
{
vtkIdType pid[1];
pid[0] = points->InsertNextPoint(cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
vertices->InsertNextCell(1, pid);
}
qDebug()<<"bbb points refrtence count:"<<points->GetReferenceCount();
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetVerts(vertices);
qDebug()<<"aaaaaaa polyData refrtence count:"<<polyData->GetReferenceCount();
qDebug()<<"ccc points refrtence count:"<<points->GetReferenceCount();
//映射
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
qDebug()<<"aaaaaaaaa mapper refrtence count:"<<mapper->GetReferenceCount();
qDebug()<<"bbbbbbb polyData refrtence count:"<<polyData->GetReferenceCount();
//演员
vtkSmartPointer<vtkActor>actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
qDebug()<<"bbbbbbbbb mapper refrtence count:"<<mapper->GetReferenceCount();
renderer->AddActor(actor);
qDebug()<<"ccccc actor refrtence count:"<<actor->GetReferenceCount();
renderer->ResetCamera();
ui->vtk_widget->GetRenderWindow()->Render();
}
void Widget::on_pushButton_3_clicked()
{
qDebug()<<"++++++++++++++++++++++++++++++";
qDebug()<<"ddddd actor refrtence count:"<<actor->GetReferenceCount();
qDebug()<<"ddd points refrtence count:"<<points->GetReferenceCount();
}
void Widget::on_pushButton_4_clicked()
{
qDebug()<<"*******************************";
qDebug()<<"ddd points refrtence count:"<<points->GetReferenceCount()<<"points num:"<<points->GetNumberOfPoints();
renderer->RemoveActor(actor);
test_points->Delete();
qDebug()<<"eeeee actor refrtence count:"<<actor->GetReferenceCount();
qDebug()<<"b test_points refrtence count:"<<test_points->GetReferenceCount();
}
运行结果
a renderer refrtence count: 1
b renderer refrtence count: 2
aaa points refrtence count: 1
a test_points refrtence count: 1
aaaaa actor refrtence count: 1
bbbbb actor refrtence count: 2
---------------------------------------------
Failed to find match for field 'rgba'.
bbb points refrtence count: 1
aaaaaaa polyData refrtence count: 1
ccc points refrtence count: 2
aaaaaaaaa mapper refrtence count: 2
bbbbbbb polyData refrtence count: 3
bbbbbbbbb mapper refrtence count: 3
ccccc actor refrtence count: 2
++++++++++++++++++++++++++++++
ddddd actor refrtence count: 2
ddd points refrtence count: 2
*******************************
ddd points refrtence count: 2 points num: 153113
eeeee actor refrtence count: 1
b test_points refrtence count: 32607