How to understand this use of New() within a struct?

I’ve usually seen New() used as follows:
vtkPolyData *pd = vtkPolyData::New();

But I’ve encountered a syntax I haven’t seen before: what does New() do in the following struct?

struct MyItem {

  struct Data : vtkObject
  {
    static Data* New();               // static pointer referencing itself??
  };
};

It seems that struct Data contains a static reference to an instance of itself - but why is it declared in that ‘self referential’ way? It’s obviously valid C++ since it compiles, but can someone explain the syntax for me?

… and later in the code:

// Initialize the static Data object - but what is happening in the struct Data definition?
`vtkStandardNewMacro(MyItem::Data);`

Thanks!

VTK objects are created using the object factory pattern.

In C++, that is a declaration of a function which can be called as a normal function i.e, without needing an instance of the struct itself.

That comment is completely wrong. It does not “initialize” the static data object (whatever that is). It creates a new instance of MyItem::Data.

The vtkStandardNewMacro expands to define the New method such that it constructs and returns an instance of MyItem::Data. It does not do any kind of initialization. The reason for the New method is to allow consumers to extend VTK by implementing object factory overrides for VTK classes.

Some classes in VTK use vtkObjectFactoryNewMacro which creates a new instance using the vtkObjectFactory.

2 Likes

Thanks Jaswant!
So the struct Data declares a static New() element:
static Data* New();

And the following defines the Data::New() function?

vtkStandardNewMacro(MyItem::Data);

If so, does the above actually get executed and instantiate a new Data object on the heap before main() is called, even if the code never calls Data::New() anywhere else? I.e. if code in main() does this:

vtkNew(MyItem::Data) vtk;

Are there now two instances of MyItem::Data on the heap?

Thanks!

No, not an element, it declares the New function.

Correct

No, it’s instantiated only when New is invoked like

MyItem::Data* instance = MyItem::Data::New();
// or using smartpointer
auto instance = vtk::TakeSmartPointer(MyItem::Data::New());
// or using vtkNew
vtkNew<MyItem::Data> instance;

I don’t understand what this means.

Oops, should be
vtkNew<MyItem::Data> vtk;

Thanks - it all makes more sense now… I’m still getting accustomed to extensive macro use in C++!