C++11开始使用智能指针管理资源,会自动管理引用计数的增加与减少,如果检测到某对象的引用计数值减少为0,则会自动释放该对象的资源,从而达到自动管理内存的目的。
VTK中创建对象有三种方式:
1.使用vtkObjectBase里的静态成员方法New()创建,用Delete()释放;
2.使用智能指针vtkSmartPointer;
3.使用RAII模式的vtkNew;
在VTK中,对象都是被创建在堆上,必须Delete释放,否则会出现内存泄漏的情况。是由于VTK将vtkObjectBase类及其子类的构造函数都声明为受保护类型,不支持自行构造创建,这样就不能自动在函数栈上创建;
使用智能指针创建对象,则无需手动调用Delete()方法减少引用计数,因为引用计数的增加与减少都是由智能指针自动完成的。VTK实现了便利的自动内存管理的概念,使用引用计数。与其他智能指针不同之处在于引用计数保留在VTK对象本身中,而不是智能指针类中。这样的好处在于:即使VTK对象作为原始指针传递,也可以增加引用计数。
vtkNew
分配并持有VTK对象。
vtkNew是一个类模板,它在构造时使用T::New()分配并初始化其模板参数的实例。它假定在其生存期内拥有一个引用,并在销毁时调用T->Delete();自动强制转换为原始指针是为了方便起见,但是如果vtnowed将在不增加其引用计数的情况下超出范围,则此方法的用户应确保不会返回此指针。可以看做是一个RAII的auto_ptr;
vtkNew被用于vtkSmartPointer的替代品,在简单环境中,可以使用vtkNew取代vtkSmartPointer;
注意:vtkNew的赋值构造函数和拷贝构造函数都被禁用;
vtkNew.h
代码位置在:Common\Core\vtkNew.h
#ifndef vtkNew_h
#define vtkNew_h
#include "vtkIOStream.h"
class vtkObjectBase;
template <class T>
class vtkNew
{
/**
* Compile time checking that the class is derived from vtkObjectBase.
*/
void CheckObjectBase(vtkObjectBase*) {}
public:
/**
* Create a new T on construction.
*/
vtkNew() : Object(T::New())
{
this->CheckObjectBase(this->Object);
}
//@{
/**
* Deletes reference to instance of T on destruction.
*/
~vtkNew()
{
T* obj = this->Object;
if (obj)
{
this->Object = nullptr;
obj->Delete();
}
}
//@}
/**
* Enable pointer-like dereference syntax. Returns a pointer to the contained
* object.
*/
T* operator->() const
{
return this->Object;
}
//@{
/**
* Get a raw pointer to the contained object. When using this function be
* careful that the reference count does not drop to 0 when using the pointer
* returned. This will happen when the vtkNew object goes out of
* scope for example.
*/
T* GetPointer() const
{
return this->Object;
}
T* Get() const
{
return this->Object;
}
operator T* () const
{
return static_cast<T*>(this->Object);
}
//@}
/**
* Dereference the pointer and return a reference to the contained object.
* When using this function be careful that the reference count does not
* drop to 0 when using the pointer returned.
* This will happen when the vtkNew object goes out of scope for example.
*/
T& operator*() const
{
return *static_cast<T*>(this->Object);
}
private:
vtkNew(vtkNew<T> const&) = delete;
void operator=(vtkNew<T> const&) = delete;
T* Object;
};
#endif