系统面向对象的、天然的特性通过各种各样的对象类型或类来描述和操作数据。当对一个特定类实例化来产生这个类的实例时,系统会分配内存来存储数据属性值和方法指针(例如纯虚函数指针表)。然后其他类或数据结构就可以用普通程序操作来引用这个对象。一般地,在程序执行过程中,当实例被删除或内存恢复时,应用将会消失。然而,确定实例何时删除是很困难的。删除实例过快会造成程序崩溃;而删除太慢会出现内存泄露(或过多消耗内存)。这种内存分配和释放的过程就是内存管理。
在 ITK
中,内存管理是通过引用计数来实现的。这和另一种普通的包括
JAVA
等其他系统使用的垃圾回收方法形成鲜明对比。在引用计数中,每个实例的应用次数将被记忆。当对象的引用计数为零时进行释放。在垃圾回收中,一个后台处理系统将自动识别并释放不再被系统引用的对象实例。与垃圾回收相关的问题是内存删除的确切时间。当对象数据很大(如以 G
为单位的三维图像)时是不可接受的。引用计数将迅速删除内存(一旦对象的所有引用消失)。
引用计数通过一个 Register( )/Delete( )
成员函数界面来实现。一个 ITK 对象的所有实例都是由引用它们的对象使用一个 Register( )方式来调用的。Register( )方式增加实例的引用数。当实例引用消失时,调用一个Delete ( )方式来减少实例的引用计数——这和UnRegister( )
方式是相同的。
当引用计数为零时,实例将消失。
使用一个称为 itk::SmartPointer
的类来大大简化这一方案。智能指针的作用与常规指针一样(
例如支持操作符
->
和
*)
:当引用一个实例时执行
Register( )
而当不再引用实例时用UnRegister( )。与
ITK
中大部分实例不同,智能指针可以指向程序块,当智能指针生成的范围关闭时会自动删除。因此,在 ITK 中就应该尽量少用 Register( )和 Delete( )。例如:
MyRegistrationFunction( )
{ <----- Start of scope
// here an interpolator is created and associated to the
// SmartPointer "interp".
InterpolatorType::Pointer interp = InterpolatorType::New( );
} <------ End of scope
在这个例子中,有一个引用计数为 1
的引用计数对象(使用 new( )
方式)。赋值给对象指针的 interp
并未改变引用计数。在程序最后,
interp
被释放,当前对象
interpolator
的引用计数减少,当减少到零时,对象 interpolator
也被释放。
注意:ITK
智能指针通常指向由
itk::LightObject
分离出来的类。方法创新和函数调用经常返回一个指向实例的真指针,但它们立即指向智能指针。当需要增加或内存命令需要一个更小、更快的类时,裸指针指向一个非 LightObject
类。