Forward Declaration error when using Qt

Here is a simple example for my problem:

// test.h
#include <QObject>
#include <vtkSmartPointer.h>

class vtkImageData;

class test : public QObject
{
 private:
  vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();

 public:
  test(/* args */) = default;
  ~test() =default;
};

// test.cxx
#include "test.h"
#include "vtkImageData.h"

Everything works fine with above code, however, if I add a Q_OBJECT macro to test class:

class test : public QObject
{
  Q_OBJECT
 private:
  vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();

 public:
  test(/* args */) = default;
  ~test() =default;
};

the compiler will produce an error:incomplete type 'vtkImageData' used in nested name specifier.

It looks like an issue due to Qt moc mechanism. Here are my questions:

  1. What exactly causes this kind of problem?
  2. Is there a way to use forward declaration with Q_OBJECT? Or I can only include the header file when Q_OBJECT macro is used?

The problem here is that you are trying to instantiate a class without telling the compiler its definition.

Move the vtkSmartPointer<vtkImageData>::New to the cxx file to fix it.

The reason it works by adding the Q_OBJECT macro is likely that triggers moc on the implementation which finds the #include <vtkImageData.h>.