Results 1 to 16 of 16

Thread: Template class

  1. #1
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Template class

    Hi,

    I have just wrote the following code ( only showing part of class ) :

    Qt Code:
    1. template<class T> class DAPointer {
    2. T* m_pPtr;
    3. public:
    4. inline DAPointer( T* p=0 ) : m_pPtr(p){}
    5. inline ~DAPointer() { m_pPtr = NULL; }
    6. // etc....
    7. };
    To copy to clipboard, switch view to plain text mode 

    What it is meant to do is just set a pointer to NULL after I've deleted it.

    For example :

    Qt Code:
    1. DAPointer<TestObject>obj;
    2. obj = new TestObject;
    3. delete obj; // <---------------- error : cannot convert from DAPointer<T> to void *
    To copy to clipboard, switch view to plain text mode 

    What am I missing in order to allow the delete function not to give conversion error?

    Kind regards,
    Steve

  2. #2
    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 class

    The delete operator works only on an actual pointer. You are using it on an object on the stack.

    That might work if you overload the delete operator. But I've never tried that before, and I don't think it could work on a non-pointer. You could make a delete() function, though.

    But I don't see why you would want to give a member-variable the value NULL if the whole object is deleted anyway (which is what's happening when the destructor is called).

    I think the delete() function is what you want.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  3. #3
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    Hi,

    I want to give the member variable NULL, just incase the user forgot, a little like how QPointer works, so I don't have any 'dangling' pointers. Thus create an object, then when I delete it, it gets set to NULL for me by this class.

    I thought the object is on the heap by having the constructor within the template class taking a pointer?

    Possible need to override delete, thus :

    Qt Code:
    1. void operator delete (void *p);
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. DAPointer<T>* pc = static_cast<DAPointer<T>*>(p);
    2. free(p);
    3. p = NULL;
    To copy to clipboard, switch view to plain text mode 

    I'll have a look, but thought I wouldn't need to do this...

    Regards,
    Steve

  4. #4
    Join Date
    May 2006
    Location
    Germany
    Posts
    108
    Thanks
    2
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Template class

    Looks very much like what QPointer does, maybe you want to take a look at the qt sources to see how the Trolls did it :-)

    Edit: you were faster than me commenting that , also I think Alexandrescu's Loki library has such a pointer.
    Last edited by Methedrine; 12th June 2007 at 11:35.
    "If you lie to the compiler, it will get its revenge." - Henry Spencer

  5. #5
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    Hi,

    I've had a look at the QPointer header class and don't see any overloaded delete function?

    This is now my class :

    Qt Code:
    1. template<class T> class DAPointer {
    2. T* m_pPtr;
    3. public:
    4. inline DAPointer( T* p=0 ) : m_pPtr(p){}
    5. inline ~DAPointer() { delete m_pPtr; m_pPtr = NULL; }
    6. inline void operator delete (void *p)
    7. { DAPointer<T>* pc = static_cast<DAPointer<T>*>(p); free(p); p = NULL; };
    8. };
    To copy to clipboard, switch view to plain text mode 

    So I thought now that the following would call the delete function above :

    Qt Code:
    1. m_pView = new CanView();
    2. delete m_pView;
    To copy to clipboard, switch view to plain text mode 

    As m_pView is DAPointer<CanView>m_pCanView

    Unfortunately, doesn't appear my delete function is being used as getting the usual cannot convertfrom DAPointer<T> to void* error...

    Anybody see anything incorrect?

    Regards,
    Steve

  6. #6
    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 class

    QPointer is used for storing pointers to objects you don't own, thus there is no point in calling delete on them. In your case you want something I recently called a hijacking pointer. In your case I don't see why would you ever want to call delete on such an object, it doesn't make sense. The object will get deleted when it runs out of scope (for example when the function it was created in returns) and when it happens, it'll delete the object contained within. I assume that by calling "delete" you'd like to delete the object pointed by the "pointer". But then you're left with an object that doesn't point to anything, so it's as good as deleting the "pointer" object itself.

    Be warned that in currect situation this will cause a problem:
    Qt Code:
    1. void func(){
    2. YourPointer ptr1(new SomeObject());
    3. YourPointer ptr2 = ptr1;
    4. } // segfault here because "SomeObject" is deleted twice
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    Thanks,

    Just wanted to set the pointer to NULL when out of scope, I know when I do a delete on an object that is of QPointer, that object is set to NULL for me.

    Still unsure why my overloaded delete function not getting called...

    Regards,
    Steve

  8. #8
    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 class

    I don't think steg90 wants to make a hijacking pointer. It is my understanding he wants normal pointers, except that a delete on them also sets them to NULL.

    Of course, you can't catch a delete that happens elsewhere in the program (where other pointers point to the same object) except if the pointer class only points to special classes that will notify it. This is what QPointer does. It can only point to QObject descendants.

    So the best you can do is make the pointer NULL after you call delete on that specific pointer. Which makes the class purely a convenience class.

    You can't overload the delete operator to take a non-pointer. That is where the compiler error comes from. So a del() function will have to do.

    Here is your convenience class:

    Qt Code:
    1. template<class T>
    2. class Pointer {
    3. public:
    4.  
    5. Pointer (T* p) {
    6. _ptr = p;
    7. }
    8.  
    9. void del() {
    10. delete _ptr;
    11. _ptr = NULL;
    12. }
    13.  
    14. // More operators. Like the dereferencing operators: * and ->
    15.  
    16. private:
    17.  
    18. T* _ptr;
    19. };
    To copy to clipboard, switch view to plain text mode 

    I just read your latest post, steg90. Why would you want to give a pointer the value NULL if it falls out of scope anyway?
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  9. #9
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    Hi,

    So I would have to call del()? Now the user needs to remember to call that...

    I thought QPointer took a new object and when I deleted that object it sets it to NULL for me, just was trying to emulate that in my own template class, but as you can see, no success...

    Regards,
    Steve

  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 class

    By the way... a somewhat smarter approach would be:
    Qt Code:
    1. template<class T> class SmartPointer {
    2. struct SPData {
    3. SPData(T *obj){ m_ptr = obj; m_count = 1; }
    4. ~SPData(){ delete m_ptr; }
    5. T* m_ptr;
    6. uint m_count;
    7. };
    8. public:
    9. SmartPointer(T *obj=0){
    10. m_data = new SPData(obj);
    11. }
    12. ~SmartPointer(){
    13. deref();
    14. }
    15. SmartPointer(SmartPointer &other){
    16. m_data = other.m_data;
    17. ref();
    18. }
    19. SmartPointer &operator=(SmartPointer &other){
    20. if(other.m_data==m_data)
    21. return *this;
    22. deref();
    23. m_data = other.m_data;
    24. ref();
    25. }
    26. SmartPointer &operator=(T *obj){
    27. if(!m_data){
    28. m_data = new SPData(obj);
    29. return *this;
    30. }
    31. if(obj==m_data->m_ptr) return *this;
    32. m_data->deref();
    33. m_data = new SPData(obj);
    34. return *this;
    35. }
    36. bool operator==(SmartPointer &other) const{ return m_data==other.m_data; }
    37. T operator*(){ return m_data ? m_data->m_ptr : T(); }
    38. const T* operator T*() const { return m_data ? m_data->m_ptr : 0; }
    39. private:
    40. SPData *m_data;
    41. void deref(){
    42. if(!m_data) return;
    43. if((--(m_data->m_count))==0){
    44. delete m_data;
    45. }
    46. }
    47. void ref(){
    48. m_data->m_count++;
    49. }
    50. int m_count;
    51. };
    To copy to clipboard, switch view to plain text mode 
    Note that this code is not reentrant and was not tested thus it probably contains some errors. Furthermore the mechanism will still break down if you delete the pointer yourself somewhere. But the advantage is that all objects track the number of references to the object and the object will get deleted when nothing points to it anymore. If you want, you can also add a possibility to force the deletion by adding the following method:
    Qt Code:
    1. void SmartPointer::forceDelete(){
    2. if(!m_data) return;
    3. delete m_data->m_ptr;
    4. m_data->m_ptr = 0;
    5. }
    To copy to clipboard, switch view to plain text mode 
    Adding isValid() or isNull() methods would also be a good move then.
    Last edited by wysota; 12th June 2007 at 12:11.

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

    steg90 (12th June 2007)

  12. #11
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    Many thanks to all of you for your suggestions and help.

    wysota - class looks cool

  13. #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 class

    Quote Originally Posted by steg90 View Post
    wysota - class looks cool
    Thx It probably doesn't work, but still thx

    A bit more about QPointer - the whole magic in QPointer is that it connects to the destroyed() signal emitted from every QObject when it gets deleted, so it's easy to synchronize all pointers and it's safe to use it when regular pointers point to the same object. The minimal implementation of QPointer is:

    Qt Code:
    1. class MyPointer : public QObject {
    2. Q_OBJECT
    3. public:
    4. MyPointer(QObject *object, QObject *parent=0){
    5. m_ptr = object;
    6. if(m_ptr)
    7. connect(m_ptr, SIGNAL(destroyed()), SLOT(_q_destroyed()));
    8. }
    9. // stuff returning and operating on the pointer goes here, like:
    10. operator T * () const{ return m_ptr; }
    11. private slots:
    12. void _q_destroyed(){
    13. m_ptr =0;
    14. }
    15. private:
    16. QObject *m_ptr;
    17. }
    To copy to clipboard, switch view to plain text mode 

  14. #13
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Template class

    I now see how QPointer is working

    I have now been using auto_ptr<T> which is pretty similar to the smart pointers you get in the boost libs.

    Regards,
    Steve

  15. #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 class

    Ask Jacek, he'll tell you that std::auto_ptr sucks

  16. #15
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Template class

    Quote Originally Posted by wysota View Post
    the whole magic in QPointer is that it connects to the destroyed() signal emitted from every QObject when it gets deleted
    Really? And how do you think it would connect to anything? QPointer does not inherit from QObject... The whole magic is, once again, what some would call a "dirty hack". It's handled somewhere in QMetaObject::addGuard() and QMetaObject::removeGuard() if I remember well (note that these functions are, of course, internals...) and proves faster (and in some cases safer) than signals/slots, especially when playing with threads...
    Current Qt projects : QCodeEdit, RotiDeCode

  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 class

    Quote Originally Posted by fullmetalcoder View Post
    Really? And how do you think it would connect to anything? QPointer does not inherit from QObject...
    It doesn't matter. The general mechanism remains the same. Signals and slots are just a manifestation of the meta-object architecture. It doesn't matter whether you call connect() or use any other method that relies on the same assumptions (read the article about dynamic signals and slots - are they really signals and really slots? does it matter?). You can perfectly well emulate QPointer with a connection to destroyed() signal, even if QPointer itself is not a QObject (it could contain one internally). There are many things in Qt that are implemented "differently" under the hood than it may seem. Designer is one of them, for example - much Qt functionality is obtained using dedicated mechanisms or dirty hacks.

Similar Threads

  1. Creating object of other class in Run() method
    By santosh.kumar in forum Qt Programming
    Replies: 2
    Last Post: 15th May 2007, 15:05
  2. Replies: 2
    Last Post: 16th March 2007, 09:04
  3. problem using template
    By mickey in forum General Programming
    Replies: 6
    Last Post: 18th November 2006, 15:57
  4. Replies: 2
    Last Post: 4th May 2006, 19:17
  5. How to propagate from one class to another
    By mahe2310 in forum Qt Programming
    Replies: 15
    Last Post: 20th March 2006, 01:27

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.