|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi everyone,
I am using a third party library that uses templates quite heavily for generalization. It is an image processing library and for example a typical "Image" class has the following definition: Image<PixelType, Dimensions> The PixelType here represents the data type of the underlying data...could be anything from chars to complex numbers and the Dimensions are the dimensions of the image...which could be 2D to 4D (3D and time). Now, my problem is that I need to instantiate and store these objects in my class. With non-templated objects it is trivial as everything is known at compile time. However, with this object, I do not know the PixelType and Dimensions till run-time! So, I cannot, for example, have a member variable in a class of the Image type. However, that is exactly what I need to do. I need to create the image object and then later access this image object and use its functions. What design options do I have? I am pretty sure people have had this problem before. What solutions can I choose from? I have banged my head against this for the last two days but have failed to come up with a good solution. Typically, how the object is going to be created is that the user will input a file at run-time and based on the file header, the Image object of the appropriate type (defined by PixelType and Dimensions) would be created. However, how do I store that pointer or object and when I want to access it later, how do I ensure that the pointer is referred to with the correct type...?? Write now I do the following to construct the object: void ConstructReader(const char * fileName) { ReadHeader(fileName, int pixelType, int dimensions); typedef Image<pixelType, dimensions> MyImage; MyImage * image = new MyImage; } Someone had suggested that I have a template class for each possible combination. However, I have about 12 pixel types and 3 dimensions to support, which already makes a 36 possible combinations for just one file format. I have about 10 to support! Can someone suggest what I can do here so as not to have some class explosion... Hope someone can provide some suggestions. Cheers, Anja |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Feb 22, 1:27am, Anja <anja.e...@googlemail.com> wrote:
> Hi everyone, > > I am using a third party library that uses templates quite heavily for > generalization. It is an image processing library and for example a > typical "Image" class has the following definition: > > Image<PixelType, Dimensions> > > The PixelType here represents the data type of the underlying > data...could be anything from chars to complex numbers and the > Dimensions are the dimensions of the image...which could be 2D to 4D > (3D and time). > > Now, my problem is that I need to instantiate and store these > objects in my class. With non-templated objects it is trivial as > everything is known at compile time. > > However, with this object, I do not know the PixelType and Dimensions > till run-time! So, I cannot, for example, have a member variable in a > class of the Image type. However, that is exactly what I need to do. I > need to create the image object and then later access this image > object and use its functions. > > What design options do I have? I am pretty sure people have had this > problem before. What solutions can I choose from? <...> It depends on the Docs for your image type. My guess is that you are meant to supply your own types, but they will need to conform to some set of rules e.g interface or concept. Anyway wrapping different entities into one can be achieved by creating a wrapper, e.g lets call it pixel . pixel contains a pointer to an abstract base class, from where you can derive your actual own pixel types. IOW something like: template < typename PixelType, typename Dimensions > struct Image { Image( Dimensions const & d) { } }; // base class for real pixel types struct abc_pixel_type{ virtual ~abc_pixel_type(){} }; // various real pixel types struct col_pixel : abc_pixel_type{ /****/ }; struct gray_pixel : abc_pixel_type{ /****/ }; struct png_pixel : abc_pixel_type{ /****/ }; // common wrapper for various pixels struct pixel{ // somehow construct form real pixels... pixel(gray_pixel const & in) : m_pixel(new gray_pixel(in)){} pixel(png_pixel const & in) : m_pixel(new png_pixel(in)){} pixel(col_pixel const & in) : m_pixel(new col_pixel(in)){} ~pixel(){ delete m_pixel;} private: abc_pixel_type * m_pixel; }; // wrap dimensions struct dimension{ dimension(int x, int y): m_xvalue(x),m_yvalue(y){} private: int m_xvalue; int m_yvalue; }; int main() { Image<pixel,dimension> my_image(dimension(1024,768)); } However this will only be useful if you make sure you conform to the requirements of the image type of course .... regrads Andy Little |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Feb 22, 2:45 am, kwikius <a...@servocomm.freeserve.co.uk> wrote:
> On Feb 22, 1:27 am, Anja <anja.e...@googlemail.com> wrote: > > > > > Hi everyone, > > > I am using a third party library that uses templates quite heavily for > > generalization. It is an image processing library and for example a > > typical "Image" class has the following definition: > > > Image<PixelType, Dimensions> > > > The PixelType here represents the data type of the underlying > > data...could be anything from chars to complex numbers and the > > Dimensions are the dimensions of the image...which could be 2D to 4D > > (3D and time). > > > Now, my problem is that I need to instantiate and store these > > objects in my class. With non-templated objects it is trivial as > > everything is known at compile time. > > > However, with this object, I do not know the PixelType and Dimensions > > till run-time! So, I cannot, for example, have a member variable in a > > class of the Image type. However, that is exactly what I need to do. I > > need to create the image object and then later access this image > > object and use its functions. > > > What design options do I have? I am pretty sure people have had this > > problem before. What solutions can I choose from? > > <...> > > It depends on the Docs for your image type. > My guess is that you are meant to supply your own types, but they will > need to conform to some set of rules e.g interface or concept. > > Anyway wrapping different entities into one > can be achieved by creating a wrapper, e.g lets call it pixel . pixel > contains a pointer to an abstract base class, from where you can > derive your actual own pixel types. > > IOW something like: > > template < > typename PixelType, > typename Dimensions > > struct Image > { > Image( Dimensions const & d) > { > } > > }; > > // base class for real pixel types > struct abc_pixel_type{ > virtual ~abc_pixel_type(){} > > }; > > // various real pixel types > struct col_pixel : abc_pixel_type{ > /****/ > > }; > > struct gray_pixel : abc_pixel_type{ > /****/ > > }; > > struct png_pixel : abc_pixel_type{ > /****/ > > }; > > // common wrapper for various pixels > struct pixel{ > > // somehow construct form real pixels... > pixel(gray_pixel const & in) > : m_pixel(new gray_pixel(in)){} > pixel(png_pixel const & in) > : m_pixel(new png_pixel(in)){} > pixel(col_pixel const & in) > : m_pixel(new col_pixel(in)){} > ~pixel(){ delete m_pixel;} > private: > abc_pixel_type * m_pixel; > > }; > > // wrap dimensions > struct dimension{ > dimension(int x, int y): m_xvalue(x),m_yvalue(y){} > private: > int m_xvalue; > int m_yvalue; > > }; > > int main() > { > Image<pixel,dimension> my_image(dimension(1024,768)); > > } > > However this will only be useful if you make sure you conform to the > requirements of the image type of course .... > > regrads > Andy Little Hi, Thanks for your reply. This is exactly my problem! In your example, this statement: > int main() > { > Image<pixel,dimension> my_image(dimension(1024,768)); > > } Say I needed to do this in a class function and created the object on the heap and needed to store the pointer in a class variable. I am stuck then! Anja |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
* Anja:
> Hi everyone, > > I am using a third party library that uses templates quite heavily for > generalization. It is an image processing library and for example a > typical "Image" class has the following definition: > > Image<PixelType, Dimensions> > > The PixelType here represents the data type of the underlying > data...could be anything from chars to complex numbers and the > Dimensions are the dimensions of the image...which could be 2D to 4D > (3D and time). > > Now, my problem is that I need to instantiate and store these > objects in my class. With non-templated objects it is trivial as > everything is known at compile time. > > However, with this object, I do not know the PixelType and Dimensions > till run-time! So, I cannot, for example, have a member variable in a > class of the Image type. However, that is exactly what I need to do. I > need to create the image object and then later access this image > object and use its functions. > > What design options do I have? I am pretty sure people have had this > problem before. What solutions can I choose from? I have banged my > head against this for the last two days but have failed to come up > with a good solution. > > Typically, how the object is going to be created is that the user will > input a file at run-time and based on the file header, the Image > object of the appropriate type (defined by PixelType and Dimensions) > would be created. However, how do I store that pointer or object and > when I want to access it later, how do I ensure that the pointer is > referred to with the correct type...?? > > Write now I do the following to construct the object: > > void ConstructReader(const char * fileName) > { > ReadHeader(fileName, int pixelType, int dimensions); > typedef Image<pixelType, dimensions> MyImage; > MyImage * image = new MyImage; > } This is not valid code. > Someone had suggested that I have a template class for each possible > combination. However, I have about 12 pixel types and 3 dimensions to > support, which already makes a 36 possible combinations for just one > file format. I have about 10 to support! > > Can someone suggest what I can do here so as not to have some class > explosion... It seems that the point of the templatization is to yield efficient operations, and that that's likely part of the reason you're using this library in the first place. Therefore, simply abstracting directly up to run-time typing would lose a main advantage of the library. Therefore, it seems you need two layers: * A templated layer that implements the higher level image operations you need in terms of the efficient library operations. For example, a clear() function implemented in terms of library's setPixel(). * A dynamically typed layer that serves as glue between the rest of the program and the library. For example, a virtual clear() function delegating to the relevant image-type-specific clear(). For the glue layer you will by necessity only have available the pixel types and dimensions you have chosen at compile time. So choose all that can conceivably be useful. Don't fret about number of combinations: just install them in an object factory repository. Then, when you need an image of run-time pixel type and dimensions, ask the factory repository for a factory object, then ask that factory object for an image object. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
![]() |
| Outils de la discussion | |
|
|