vtkObjectBase主要实现引用计数,因此vtkObject及其子类也都继承了该特性。vtkObject中实现了在VTK中非常广泛使用的观察者/命令机制,能够方便地处理消息响应,例如处理鼠标消息、键盘消息、进度消息等,VTK中Widget中大量使用了该机制进行消息处理。vtkObject中定义了一个vtkSubjectHelper对象来管理观察者。vtkSubjectHelper内部定义了一个观察者vtkObserver对象链表。vtkObserver表示一个观察者,其内部定义了一个vtkCommand指针,一个消息ID以及一个表示优先级的变量。当观察者监听到一个消息ID,就响应vtkCommand定义的回调函数。
vtkObject通过如下函数添加和删除观察者:
unsigned long AddObserver(unsigned long event, vtkCommand*,float priority = 0.0f);
void RemoveObserver(unsigned long tag);
AddObserver用于添加一个观察者。当执行该函数时,vtkSubjectHelper对象根据event、vtkCommand对象和priority参数封装为一个vtkObserver,并根据优先级priority顺序添加至观察者列表中。
vtkObjectBase is the base class for all reference counted classes in the VTK. These classes include vtkCommand classes, vtkInformationKey classes, and vtkObject classes.
vtkObject作为VTK类库中目标对象的基类。vtkObject通过注册感兴趣的事件,把Command和事件联系在一起,然后编写回调函数响应事件的发生。例如vtkRenderer当信息StartEvent发生时,开始对数据进行渲染,而当消息EndEvent发生时停止渲染。任意一个VTKObject的实例可以通过调用AddObserver()方法来添加对事件的观察,只需要将事件的id和自定义的回调函数进行关联,VTK就能方便的实现消息的处理。
vtkObject的所有的子类必须用New()方法创建,用Delete()方法删除。因为构造函数时保护的。New()一个静态方法,使用Factory设计模式来创建一个实例。VTK里的类,构造函数和析构函数都是受保护类型。
vtkObjectBase的构造函数、析构函数、拷贝函数以及“=”操作符都被声明为“protected”类型。
VTK对象都是通过内部定义静态函数New()来生成,因此构造函数、析构函数都要定义为protected类型。而对与赋值“=”运算符和拷贝构造函数定义为private类型,只做声明不用实现。如上图所示。
对于继承自vtkObjectBase的类,必须覆盖New()来生成一个实际类的对象,而不是得到一个vtkObjectBase对象;对于Delete()函数,直接继承自vtkObjectBase类即可。在类定义中声明一个共有静态函数New(),如上图所示,在头文件中加入
static vtkTestClass *New();
在实现文件构造函数之前加入如下代码:
vtkStandardNewMacro(vtkTestClass);
如下图所示:
vtkStandardNewMacro是VTK中定义的一个宏,作用是定义一个通用的New()函数 ,使用时需要将实际的类名传递给它。
这些基本函数包括GetClassNameInternal()、IsTypeOf()、IsA()、SaftDownCast()、NewInstanceInternal()、NewInstance()等。这些函数在vtkObjectBase中定义,用户需要在子类中覆盖这些函数。不过,借助VTK的宏定义,不需要重新实现这些函数。
vtkTypeMacro(vtkTestClass,vtkObject);
对于一个类的成员变量,通常都需要定义相应的Set()和Get()函数。VTK也提供了多种类型的宏来定义一不同类型的成员变量设置函数。比如对于一个标量数据成员,可以使用vtkSetMacro和vtkGetMacro宏。
覆盖基类PrintSelf()函数,实现打印当前类对象的状态。
#ifndef __vtkTestClass_h
#define __vtkTestClass_h
#include
class vtkTestClass: public vtkObject
{
public:
vtkTypeMacro(vtkTestClass,vtkObject);
static vtkTestClass *New();
vtkGetMacro(Flag, bool);
vtkGetMacro(Speed, double);
vtkGetVector3Macro(Position,double);
vtkSetMacro(Flag,bool);
vtkSetMacro(Speed,double);
vtkSetVector3Macro(Position,double);
vtkBooleanMacro(Flag, bool);
void PrintSelf(ostream &os, vtkIndent indent);
private:
double Speed;
double Position[3];
bool Flag;
protected:
vtkTestClass();
~vtkTestClass();
private:
vtkTestClass(const vtkTestClass&); // Not implemented.
void operator=(const vtkTestClass&); // Not implemented.
};
#endif
#include "vtkTestClass.h"
#include "vtkObjectFactory.h"
vtkStandardNewMacro(vtkTestClass);
vtkTestClass::vtkTestClass()
{
Flag = false;
Speed = 0;
Position[0] = 0;
Position[1] = 0;
Position[2] = 0;
}
vtkTestClass::~vtkTestClass()
{
}
void vtkTestClass::PrintSelf(ostream &os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << "Position: " << Position[0] << " "
<< Position[1] << " "
<< Position[2] << std::endl
<< "Speed: "<<Speed<<std::endl
<< "Flag:"<<Flag<<std::endl;
}