I am trying to create a class that can represent different kind of images by using templates. For that, I have created a generic base class (should never be initialized) where the template argument defines how the pixel values should be stored (primarily float
or unsigned char
).
// Image.h
#pragma once
template<typename T>
class Image
{
public:
Image () : width (0), height (0), allocatedMemory (0), data (nullptr) {}
virtual ~Image () { delete [] data; }
protected:
int width; // in pixel
int height; // in pixel
int allocatedMemory; // number elements in data
T* data; // image data
};
Now, I have another class ColorImage
which is derived from Image
. It adds another template argument that defines the colour space of the Image:
// ColorImage.h
#pragma once
#include "Image.h"
/**
* Defines various color spaces.
* Declared outside of class because of template.
**/
enum class ColorSpace
{
CS_GRAY = 0, CS_RGB, CS_BGR, CS_HSV, CS_LAB, CS_RGBA, CS_BGRA, CS_ARGB
};
template<typename T, ColorSpace C>
class ColorImage;
// Specialise for T = unsigned char
template<ColorSpace C>
class ColorImage<unsigned char, C> : Image<unsigned char>
{
public:
ColorImage () : Image () {}
~ColorImage () {}
template<ColorSpace D>
void convert (ColorImage<unsigned char, D>* output)
{
output->width = width; // error
output->height = height; // error
output->allocatedMemory = allocatedMemory; // error
output->foo = 42; //error
// ... output->data handling here ...
}
private:
int foo;
};
In the convert()
function, I want to convert one colour space to another. For that, I want to copy all data from my original image to output
-Image. However, when I call output->width
and so on, I get the error C2248: 'Image::width' : cannot access private member declared in class 'Image'
.
I also can not access other private members from the other specialisations. output->foo = 42
(see above) throws Cannot access private member declared in class 'ColorImage'. I know I could resolve this by declaring all full specialisations as a friend
for the partial specialization, however, that would result in a massive amount of friend
-declarations, since I would have to do that for every single full specialisation (for each possible colour space). I also know I could just declare something like a public setFoo (int value)
, but I don't want to do that either since I don't want to expose the variable to the public. Is there another way of achieving this?
Thanks a lot in advance.