//vtkStandardNewMacro 其实就是定义类的静态函数New,内部就是new className
#define vtkStandardNewMacro(thisClass) \
thisClass* thisClass::New() { VTK_STANDARD_NEW_BODY(thisClass); }
#define VTK_STANDARD_NEW_BODY(thisClass) \
auto result = new thisClass; \
result->InitializeObjectBase(); \
return result
//vtkObjectFactoryNewMacro(vtkRenderWindow);通过类的名字从单例工厂里面获取,如果找不到在用new className
#define vtkObjectFactoryNewMacro(thisClass) \
thisClass* thisClass::New() \
{ \
vtkObject* ret = vtkObjectFactory::CreateInstance(#thisClass, false); \
if (ret) \
{ \
return static_cast<thisClass*>(ret); \
} \
auto result = new thisClass; \
result->InitializeObjectBase(); \
return result \
}
//VTK_MODULE_INIT(vtkRenderingOpenGL2);实例化一个模块:定义一个全局静态变量,在构造函数中调用对应模块的全局函数xxx_AutoInit_Construct()
#define VTK_MODULE_INIT(M) \
static struct M##_ModuleInit \
{ \
M##_ModuleInit() { M##_AutoInit_Construct(); } \
} M##_ModuleInit_Instance; \
//VTK_CREATE_CREATE_FUNCTION(vtkWin32OpenGLRenderWindow)
//具体类的创建函数在对应的具体工厂类中定义
#define VTK_CREATE_CREATE_FUNCTION(classname) \
static vtkObject* vtkObjectFactoryCreate##classname() { return classname::New(); }
//演示vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();是如何创建vtkRenderingOpenGL2子类的
//step1、静态注册vtkRenderingOpenGL2模块,在该模块中注册vtkRenderingOpenGL2的创建方法
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
//展开:实例化一个vtkRenderingOpenGL2ObjectFactory工厂类,把具体工厂类的实例存在基类的静态变量中
void vtkRenderingOpenGL2_AutoInit_Construct()
{
vtkRenderingOpenGL2ObjectFactory* factory = vtkRenderingOpenGL2ObjectFactory::New();
if (factory)
{
vtkObjectFactory::RegisterFactory(factory);
}
}
//展开vtkRenderingOpenGL2ObjectFactory::New(),在具体类工厂的构造函数中注册对应类的创建函数
vtkRenderingOpenGL2ObjectFactory::vtkRenderingOpenGL2ObjectFactory()
{
//创建函数、基类、子类的关系就对应了起来:vtkRenderWindow::New会调用vtkWin32OpenGLRenderWindow的new
this->RegisterOverride("vtkRenderWindow", "vtkWin32OpenGLRenderWindow", vtkObjectFactoryCreatevtkWin32OpenGLRenderWindow);
//还可以注册其他的类
this->RegisterOverride(...);
}
//真正的创建函数,是在对应工厂类中通过宏定义的
VTK_CREATE_CREATE_FUNCTION(vtkWin32OpenGLRenderWindow)
//展开
vtkObject *vtkObjectFactoryCreatevtkWin32OpenGLRenderWindow()
{
return vtkWin32OpenGLRenderWindow::New();
}
//step2、实例化过程
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
//在vtkRenderWindow中
vtkObjectFactoryNewMacro(vtkRenderWindow);
//展开
vtkRenderWindow* vtkRenderWindow::New()
{
//
vtkObject* ret = vtkObjectFactory::CreateInstance("vtkRenderWindow", false);
if(ret)
return static_cast<vtkRenderWindow*>(ret);
else
return new vtkRenderWindow();
}
//vtkObjectFactory::CreateInstance的实现
vtkObject* vtkObjectFactory::CreateInstance(const char* vtkclassname, bool)
{
vtkObjectFactory* factory = vtkObjectFactory::getXXX(vtkclassname);
vtkObject* newobject = factory->CreateObject(vtkclassname);//内部调用vtkObjectFactoryCreatevtkWin32OpenGLRenderWindow()
if (newobject)
{
return newobject;
}
return nullptr;
}
- 里面用到了工厂方法模式:每个举例类分别对应一个该类的工厂,伪代码如下:
定义:
A:Abase
B:Bbase
AFactory:Factory
BFactory:Factory
使用:
Abase* a = Factory::Create("A")//内部会实例化A而非Abase;
- 回到vtk,上面代码列举
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
是如何创建vtkRenderingOpenGL2子类的
1、如果没有VTK_MODULE_INIT(vtkRenderingOpenGL2);
那么就是new vtkRenderWindow
2、如果定义VTK_MODULE_INIT(vtkRenderingOpenGL2);
那么就是new vtkRenderingOpenGL2
3、这种方式不需要修改内部的代码,原理就是通过宏和静态对象的初始化,对具体类的工厂进行静态注册,基类对象的New方法内要通过工厂进行创建,工厂中如果找到该类对应的字符串对应的创建函数即this->RegisterOverride("vtkRenderWindow", "vtkWin32OpenGLRenderWindow", vtkObjectFactoryCreatevtkWin32OpenGLRenderWindow);就调用vtkObjectFactoryCreatevtkWin32OpenGLRenderWindow