vtk模块加载流程

博客介绍了C++中工厂方法模式,每个举例类对应一个工厂。还以vtk为例,说明创建vtkRenderingOpenGL2子类的方式,若未定义VTK_MODULE_INIT则new vtkRenderWindow,定义了则new vtkRenderingOpenGL2,其原理是通过宏和静态对象初始化进行静态注册。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值