Search code examples
c++itk

Invalid conversion of child class pointer


In the following code:

#include "itkImage.h"
#include "itkImageRegionIterator.h"

struct CustomImageBase
{
  virtual void DoSomething() = 0;
};

template <typename TPixel>
struct CustomImage : public itk::Image<TPixel, 2>, public CustomImageBase
{
  void DoSomething()
  {
    itk::Index<2> index;
    index.Fill(0);
    std::cout << this->GetPixel(index);
  }
};

int main(int, char *[])
{
  std::vector<CustomImageBase*> images;

  CustomImage<float>* floatImage = CustomImage<float>::New().GetPointer();
  CustomImage<int>* intImage = CustomImage<int>::New().GetPointer();

  return EXIT_SUCCESS;
}

I get the error: invalid convsion from itk::Image* to CustomImage*

Note that this works fine:

itk::Image<float>* testFloatImage = itk::Image<float>::New().GetPointer();

Since CustomImage inherits from itk::Image, I don't understand the problem?


Solution

  • If B derives from A, you cannot convert A* to B*. If C also derives from A, and your A* really points to a C object instead of a B object, what would happen if you pretend it is a B? The conversion is unsafe. In your case, you know that GetPointer() will always return a CustomImage<T>. The compiler does not know that. You can tell it by using a cast:

    CustomImage<float>* floatImage = static_cast<CustomImage<float>*>(CustomImage<float>::New().GetPointer());
    

    Edit: this is precisely why the conversion is unsafe: after reading the comments on your question, I don't believe CustomImage<float>::New().GetPointer() really points to a CustomImage, and if not, the cast would simply turn compiler errors into runtime errors.