[Insight-users] Forward references to ITK classes
Paul Yushkevich
pauly@cognitica.com
Sun, 30 Mar 2003 15:38:50 -0500
I have a [rather long] question about using forward references to ITK
classes. My guess is that I am not the first person to face this issue,
but I have not seen any questions regarding this on the mailing list.
Suppose I have the following situation:
A templated class Wrapper<TPixel> encapsulates a generic image
processing task and contains pointers to multiple images and filters.
This class is used throughout a large application. The class is
declared in the header file "Wrapper.h", and this file is included by
many other files in the application.
In order to reduce compilation time, I would like to use forward
references to ITK classes needed to declare the class Wrapper in the
header "Wrapper.h". The following declaration is possible:
// Forward references, no need to include ITK headers here
namespace itk {
template <int i, class T> class Image;
template <class TInput, class TOutput> class SomeFilter;
};
template <class TPixel> class Wrapper {
typedef itk::Image<3,TPixel> ImageType; // and so on
private:
ImageType *m_FirstImage,*m_SecondImage; // and so on
};
This works fine but... this declaration does not use SmartPoitners. As
soon as I try to use smart pointers, foward referencing seems to break.
A declaration of type
typedef typename ImageType::Pointer ImagePointer;
does not work because the compiler does not know that ::Pointer is part
of class itk::Image. Neither does the following declaration, which
makes a forward reference to itk::SmartPointer:
namespace itk {
...
template <class T> class SmartPointer;
};
...
typedef typename itk::SmartPointer<ImageType> ImagePointer;
...
This does not work because the compiler can not allocate room for
smartpointers without having seen them declared. If I do include the
header itkSmartPointer.h, as in the following example, the code still
does not work
#include <itkSmartPointer.h>
namespace itk {
template <int i, class T> class Image;
template <class TInput, class TOutput> class SomeFilter;
};
template <class TPixel> class Wrapper {
typedef itk::Image<3,TPixel> ImageType;
typedef typename itk::SmartPointer<ImageType> ImagePointer;
private:
ImagePointer m_FirstImage,m_SecondImage; // and so on
};
This code does not compile (at least with VC60), and I get an error in
itkSmartPoitner.h in the function Unregister(). This inline function
can not be compiled using forward references to the class over which the
SmartPointer is templated (in this case, itk::Image). If I comment out
the code in this function, the code does compile. Curiously, the
function Register() compiles just fine; the difference between them
seems to come from the fact that UnRegister is used in the desctructor
~SmartPointer().
Finally, I tried another solution, which does not use forward
references. I declared Wrapper as an abstract class with only virtual
members and no attributes. I declared a class WrapperImplementation
that iherits from Wrapper and declares all the ITK SmartPointers and
stuff. The header for WrapperImplementation includes all the ITK
headers. I included "WrapperImplementation.h" only in the places in the
code where new instances of WrapperImplementation are created. This
solution does not work well if I want to have an inheritance structure
rooted at Wrapper: e.g., classes ColorWrapper and GreyWrapper that
extend WrapperImplementation. In order to declare these classes, I have
to include "WrapperImplementation.h", and in order to use them
throughout the application I would again end up including ITK headers in
many places in the application.
So that's the dilemma, and my questions are
1. Has anyone been using forward references to ITK classes successfully?
2. Is there another way to avoid having to recompile lots of code when
including ITK headers in widely used headers such as Wrapper.h?
3. Could the SmartPointer.h be modified to allow forward referencing?
4. There is a macro directive in the ITK .h files that allows manual
instantiation of templates. Can that be used across platforms?
Thank you very much for replying!
Paul.