Results 1 to 16 of 16

Thread: Template classes and abstraction of type

  1. #1
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Template classes and abstraction of type

    I have a template class with a lot methods for 3D operations, to be able to perform the operations on different types T(for the moment only unsigned char and unsigned short). I would like to set the type of the 3D array of a certain type T, be able to perform a lot of operations on this data regardless of the type and retrieve the type when I need type-related data from it (for example a slice of the volume).

    Currently I create a class with pointers to instantiations of the classes with all possible data types, a selector to determine the current type, and I add a method for each underlying method of the template class, which calls the right version. This seems quite cumbersome, and needs a change of the wrapper implementation each time the template class is changed.

    Is there a way to do something like the following :

    Qt Code:
    1. template<class T>
    2. class A
    3. {
    4. public:
    5. void doSomething();
    6. void doSomethingToo();
    7. private:
    8. T** data;
    9. //...
    10. };
    11.  
    12. class AWrapper
    13. {
    14. public:
    15. //Do not explicitly add methods
    16. T* operator->();//Return right pointer based on typeSelector_;
    17. private:
    18. int typeSelector_;
    19. A<char>* charData_;
    20. A<short>* shortData_;
    21. };
    To copy to clipboard, switch view to plain text mode 

    Off course this does not work since T is still undefined in the wrapper. Any way to accomplish this?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    How about using dynamic_cast?

  3. #3
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    I don't really see how to use a dynamic_cast in this construction. The key seems to be overloading the dereferencing operator, but here I always need to return a type. And that type is not known in advance in my case.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    Could you try to describe with more details what you are trying to do? What you wrote earlier seems unclear to me. What is the cast operator for? How would you like to use it and in what situation?

  5. #5
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    Well, I have a 3D volume class which looks like this:

    Qt Code:
    1. template<class T>
    2. class Array2D;
    3.  
    4. template<class T>
    5. class Array3D;
    6.  
    7. template<class T>
    8. class Volume
    9. {
    10. public:
    11. //All these methods operate on data3D_ and calling them should not require knowledge of the datatype
    12. //A lot of methods are of this type !
    13. void loadVolume();
    14. void exportVolume();
    15.  
    16. void performSomeOtherOperation();
    17.  
    18. //These operations ARE type specific
    19. //Only a small number of methods are of this type
    20. T* extractSlice(int zPosition);
    21. void setSliceAt(int zPosition, Array2D<T>& slice);
    22.  
    23.  
    24. private :
    25. //Type can be U8 or U16 based on file format when loading data
    26. Array3D<T>* data3D_;
    27. };
    To copy to clipboard, switch view to plain text mode 

    I then need a second class which should do the following:

    Qt Code:
    1. //No template !!
    2. class VolumeWrapper
    3. {
    4. public:
    5. //All methods not requiring knowledge of the datatype should not be redefined
    6. //This can not compile because only type of return value differs
    7. Volume<char>* operator->() {if (charType_) return data3DChar_; else //Do nothing? This should never occur because if type short, first version should be called}
    8. Volume<short>* operator->() {if (!charType_) return data3DShort_;} else //Do nothing? This should never occur because if type short, second version should be called}
    9.  
    10. //These operations ARE type specific
    11. //User should first retrieve data type based on charType_ and use right version
    12.  
    13. //These can not compile because only type of return value differs
    14. Array2D<char>* extractSlice(int zPosition);
    15. Array2D<short>* extractSlice(int zPosition);
    16.  
    17. void setSliceAt(int zPosition, Array2D<char>& slice);
    18. void setSliceAt(int zPosition, Array2D<short>& slice);
    19.  
    20.  
    21. private :
    22. //Type can be U8 or U16 based on file format
    23. Volume<char>* data3DChar_;
    24. Volume<short>* data3DShort_;
    25. bool charType_;
    26. };
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Template classes and abstraction of type

    When is the _charType value determined?

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    Can't you have a common base class for all Volume types and return the base class pointer and later on use casting to determine which real class it is?

  8. #8
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    @jacek

    The type can already be determined in the constructor of VolumeWrapper. Normally it would be done when calling loadVolume, and the type would be determined based on the type of image files which are loaded (U8 or U16). But it is not so difficult to poll a file's type before creating the object. But nevertheless, from then on a lot of methods are used where the type should not be specified.

    @wysota

    Do you mean something like this:

    Qt Code:
    1. /*Pure abstract class, only has type specified and lists all methods operating on the
    2.   volume data, but not requiring explicit exposure of type.*/
    3.  
    4. class VolumeGeneral
    5. {
    6. public:
    7. enum type
    8. {
    9. typeUnknown,
    10. typeU8,
    11. typeU16
    12. };
    13.  
    14. VolumeGeneral(void);
    15. ~VolumeGeneral(void);
    16.  
    17. type getType() const;
    18.  
    19. virtual void init() = 0;
    20. virtual void doSomething() = 0;
    21.  
    22. protected:
    23. type type_;
    24. };
    25.  
    26. VolumeGeneral::VolumeGeneral(void)
    27. {
    28. type_ = typeUnknown;
    29. }
    30.  
    31. VolumeGeneral::~VolumeGeneral(void)
    32. {
    33. }
    34.  
    35. VolumeGeneral::type VolumeGeneral::getType() const
    36. {
    37. return type_ ;
    38. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. /*Class containing all actual code. Methods operating on data are overridden to actually
    2.   do something. Type-specific methods are added to allow an extra interface for these
    3.   operations.*/
    4.  
    5. template <class T>
    6. class VolumeSpecified : public VolumeGeneral
    7. {
    8. public:
    9. VolumeSpecified(void);
    10. ~VolumeSpecified(void);
    11.  
    12. void init();
    13. void doSomething();
    14.  
    15. void setData(T& data);
    16. T getData() const;
    17.  
    18. private:
    19. T data_;
    20. };
    21.  
    22. template <class T>
    23. VolumeSpecified<T>::VolumeSpecified(void)
    24. {
    25. if (typeid(T) == typeid(unsigned char))
    26. type_ = typeU8;
    27.  
    28. else if (typeid(T) == typeid(unsigned short))
    29. type_ = typeU16;
    30.  
    31. //else keep typeUnknown (already set)
    32. }
    33.  
    34. template <class T>
    35. VolumeSpecified<T>::~VolumeSpecified(void)
    36. {
    37. }
    38.  
    39. template <class T>
    40. void VolumeSpecified<T>::setData(T& data)
    41. {
    42. data_ = data;
    43. }
    44.  
    45. template <class T>
    46. T VolumeSpecified<T>::getData() const
    47. {
    48. return data;
    49. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. /*Use of the classes in the main program*/
    2.  
    3. //Check for type of files and allocate based on type
    4. VolumeGeneral* volume = new VolumeSpecified<unsigned short>();
    5.  
    6. //Perform type specific operations
    7. if (volume->getType() == VolumeGeneral::typeU16)
    8. {
    9. VolumeSpecified<unsigned short>* volumeS = dynamic_cast<VolumeSpecified<unsigned short>*>(volume);
    10. volumeS->setData(365);
    11. }
    12.  
    13. //Perform general operations
    14. volume->init();
    15. volume->doSomething();
    16.  
    17. delete volume;
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 28th March 2008 at 15:45. Reason: wrapped too long lines

  9. #9
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Template classes and abstraction of type

    Sorry, but I'm having difficulty understanding why you need wrappers of any kind. All your wrapper seems to be doing is introduce an unnecessary syntax (wrapperNotPointer->volumeFunction).

    If you ask me, you only need your Volume class. Without any changes (except I'm fuzzy on the return type of extractSlice).

    Qt Code:
    1. template <class T>
    2. class Volume {
    3. public:
    4.  
    5. void loadVolume();
    6.  
    7. void exportVolume();
    8.  
    9. void performSomeOtherOperation();
    10.  
    11. Array2D<T>* extractSlice(int zPosition);
    12.  
    13. void setSliceAt(int zPosition, Array2D<T>& slice);
    14.  
    15. private:
    16.  
    17. Array3D<T>* data3D_;
    18. };
    To copy to clipboard, switch view to plain text mode 
    Last edited by Michiel; 29th March 2008 at 11:54.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    Quote Originally Posted by Raistlin View Post
    @wysota

    Do you mean something like this:
    Yes and no. I don't see a need for any wrapper here. Returning the base class pointer and using dynamic_cast should be sufficient to determine everything you need. Unless of course you have some wicked usecase in mind which you are not telling us about.

  11. #11
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    I modified the example a bit to make it a bit more clear. I use a single value to type T here for simplicity, but of course this not what happens in reality. But it is just to illustrate the idea.

    Qt Code:
    1. /*Use of the classes in the main program*/
    2.  
    3. //Check for type of files and allocate based on type
    4. VolumeGeneral::type imageType;
    5.  
    6. //Determine the type based on input files
    7. ...
    8.  
    9. //Allocate with righ type
    10. VolumeGeneral* volume = 0;
    11.  
    12. if (imageType == typeU16)
    13. volume = new VolumeSpecified<unsigned short>();
    14.  
    15. else if (imageType == typeU8)
    16. volume = new VolumeSpecified<unsigned char>();
    17.  
    18. else
    19. break;
    20.  
    21. //Perform general operations
    22. volume->init();
    23. volume->doSomething();
    24.  
    25. //Perform type specific operations
    26. if (volume->getType() == VolumeGeneral::typeU16)
    27. {
    28. VolumeSpecified<unsigned short>* volumeS = dynamic_cast<VolumeSpecified<unsigned short>*>(volume);
    29. unsigned short testVariable = volumeS->getData();
    30. }
    31.  
    32. delete volume;
    To copy to clipboard, switch view to plain text mode 

    I don't see how I can do this without the extra class. If I only have my template class, I always need to specify the type, right? I can not use an object of type template class T without specifying T. So I need a base class which does not have any type to provide an interface.

    What do you mean by using a 'base class pointer' when you say I don't need a wrapper? It seems like I need to list all methods in my abstract base class, since I need it as interface for my methods. If you talk about casting some base class pointer to the right template type, it seems this is something I always need to do, regardless whether I am exporting or importing data, or I am doing something where the type does not need to be visible.

    Maybe I just need some example code on how to apply what you mean in my case, since it seems I am missing out on something ...

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    Qt Code:
    1. class Image {
    2. public:
    3. virtual void init() = 0;
    4. virtual void doSomething() = 0;
    5. virtual ~Image(){}
    6. };
    7.  
    8. class Image16 : public Image {
    9. public:
    10. Image16(unsigned short *data){
    11. //...
    12. }
    13. void init(){ ... }
    14. void doSomething(){ ... }
    15. };
    16.  
    17. class Image8 : public Image {
    18. //...
    19. };
    20.  
    21. Image *img;
    22. if(type==16)
    23. img = new Image16(data);
    24. else img = new Image8(data);
    25. img->init();
    26. img->doSomething();
    To copy to clipboard, switch view to plain text mode 

    Isn't that what you want? You don't reference the actual class type anywhere apart from calling the constructor, so there is no problem of not knowing the type.

  13. #13
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    Thank you for that code wysota. However, it seems like I am basically doing the same thing. The only difference I see is that your solution has less code because you do not keep track of the type in your base class. However, I sometimes do need to do some type-specific operations (like in the example) to interface with the main program, so I have to keep track of it to get out the right type of data.

    In conclusion, this is already a lot cleaner than what I started from. The only thing I need to do is to add all non-type specific methods as pure virtual methods to the base class.

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    Quote Originally Posted by Raistlin View Post
    However, I sometimes do need to do some type-specific operations (like in the example) to interface with the main program, so I have to keep track of it to get out the right type of data.
    Qt Code:
    1. if((Image16 *image16 = dynamic_cast<Image16*>(img))!=0){
    2. image16->specificMethod16();
    3. } else if((Image8 *image8 = dynamic_cast<Image8*>(img))!=0){
    4. image8->specificMethod8();
    5. } else {
    6. std::cerr << "Unknown Image subclass encountered" << std::endl;
    7. }
    To copy to clipboard, switch view to plain text mode 

  15. The following user says thank you to wysota for this useful post:

    Raistlin (1st April 2008)

  16. #15
    Join Date
    Aug 2006
    Posts
    44
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template classes and abstraction of type

    Oh, thanks for that addition. I did not know casting to the wrong type returned 0 instead of a junk value.

  17. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Template classes and abstraction of type

    That's the idea of dynamic_cast. If your Image class inherited QObject, you could also use qobject_cast.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.