Results 1 to 3 of 3

Thread: Alternatives to raw pointers and design suggestions needed

  1. #1
    Join Date
    Feb 2012
    Posts
    6
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Alternatives to raw pointers and design suggestions needed

    Hi,

    I have the following code:

    Qt Code:
    1. BinaryEncodedDictionary* BinaryMetaDataDecoder::parse(QIODevice *sourceDevice) {
    2. qDebug() << "Received a QIODevice to parse from!";
    3.  
    4. if(sourceDevice->peek(1) != "d") {
    5. qDebug() << "Input stream contains an invalid input file";
    6. return 0;
    7. }
    8. else {
    9. qDebug() << "Found a dictionary, valid file";
    10. return parseDictionary(sourceDevice);
    11. }
    12. }
    13.  
    14. BinaryEncodedDictionary* BinaryMetaDataDecoder::parseDictionary(QIODevice *stream) {
    15. //... Implementation will follow here
    16. return new BinaryEncodedDictionary;
    17. }
    18.  
    19. BinaryEncodedInteger* BinaryMetaDataDecoder::parseInteger(QIODevice *stream) {
    20. //... Implementation will follow here
    21. return new BinaryEncodedInteger;
    22. }
    23.  
    24. BinaryEncodedString* BinaryMetaDataDecoder::parseString(QIODevice *stream) {
    25. //... Implementation will follow here
    26. return new BinaryEncodedString;
    27. }
    28.  
    29. BinaryEncodedList* BinaryMetaDataDecoder::parseList(QIODevice *stream) {
    30. //... Implementation will follow here
    31. return new BinaryEncodedList;
    32. }
    To copy to clipboard, switch view to plain text mode 

    All of the classes above are plain old C++ classes (not inheriting from QObject) and part of
    the following class hierarchy:

    Pure virtual (super) class: BinaryEncodedAbstractType
    Child (inheriting classes): BinaryEncodedDictionary, BinaryEncodedInteger, BinaryEncodedString, BinaryEncodedList

    BinaryEncodedDictionary is implemented like this:

    Qt Code:
    1. //binaryencodeddictionary.h
    2. class BinaryEncodedDictionary : public BinaryEncodedAbstractType {
    3. public:
    4. BinaryEncodedDictionary();
    5. //TODO: Delete pointers contained by hashMap
    6. ~BinaryEncodedDictionary();
    7. private:
    8. QHash<BinaryEncodedString*, BinaryEncodedAbstractType*> hashMap;
    9. };
    10.  
    11. //binaryencodeddictionary.cpp
    12. BinaryEncodedDictionary::BinaryEncodedDictionary() {
    13. hashMap = new QHash<BinaryEncodedString*, BinaryEncodedAbstractType*>();
    14. }
    15.  
    16. BinaryEncodedDictionary::~BinaryEncodedDictionary() {
    17. //TODO: We need to remove dynamically allocated values (needed for polymorphism)
    18. }
    To copy to clipboard, switch view to plain text mode 

    The hashMap member above contains the heap-allocated return values from calls to parse*() functions as keys
    and values. Without going further into implementation details (if not needed), my main concern is the
    deletion of objects allocated by the parse*() functions. The returned BinaryEncodedDictionary from parse()
    function contains the pointers to these objects through the hashMap member variable.

    I am trying to make sure that the objects are de-allocated when BinaryEncodedDictionary goes out of scope eventually,
    and at the same time, I would like to make use of QScopedPointer and/or QSharedPointer in order not to have
    to deal with manually freeing the memory with delete.

    How could I use above in my code? I am planing to return QScopedPointers instead of raw pointers as the return
    values from the functions above, but will it be enough or do I have to do anything more? Any other suggestions?

    I am very thankfull to any kind of desing improvement suggestions as well.

    Thank you in advance.

    Kind Regards,
    Veroslav

  2. #2
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Alternatives to raw pointers and design suggestions needed

    Instead of making hashMap a pointer that you initialize to a new QHash<...>, you can almost certainly just make it a QHash<...>. (I’m assuming the declaration of hashMap you gave is missing an *, since you assign a new QHash to it.) Note that QHash is one of Qt’s implicitly shared classes. Because of that, there is no need to pass around QHash pointers to avoid copying lots of data; you can pass QHash values instead. (That might or might not make much difference in your design.)

    I could be missing something, but I don’t think QScopedPointer is going to help you here. Your various parseXxxxx methods are essentially factories; it wouldn’t make any sense (ever, I think) to return a QScopedPointer from such a function, though you could assign the return value to a QScopedPointer. If I’m reading this right, though, that wouldn’t make any sense here either, because the lifetime of those objects isn’t controlled by the scope in which the factory functions are called, but by the lifetime of the top-level BinaryEncodedDictionary.

    I don’t think you can avoid having to have the destructor for a BinaryEncodedDictionary clean up the objects to which its QHash’s keys and values point. (You can’t use a QScopedPointer for the key or value types because it isn’t an assignable data type.) QSharedPointer is a possibility, though it’s not clear to me that it would be better than just writing the appropriate destructor code. I don’t think you need “smart pointers” for this; they would just hide the deletes that must be done either way behind an extra layer of classes to understand.

    A discussion of Qt pointer wrappers that might be helpful, if you do choose to use them:
    Count with me: how many smart pointer classes does Qt have?

  3. The following user says thank you to Coises for this useful post:

    veroslav (6th September 2012)

  4. #3
    Join Date
    Feb 2012
    Posts
    6
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Alternatives to raw pointers and design suggestions needed

    Coises,

    first let me thank you for your thorough and consise answer. There were quite a few good tips in there
    and I realize that I need to do more reading on the topic, especially on Qt containers and pointer/memory
    management.

    The main reason I created this thread was to find out whether I should use the smart pointers at all (I was
    trying to avoid manually calling delete as I read you should avoid it if possible). I wanted to check that
    it was possible to avoid it in my case and you confirmed to me what I suspected from the beginning: delete
    may just be more appropriate to use in my case.

    I will need to read your reply few more times to take it all in, and then I will give it a go and try to
    come up with some good implementation. Now I have something to bite my teeth in!

    Again, thank you very much for giving me some tips to get going again. I will post back in case I hit problems
    again. It's fun learning again!

    Kind Regards,
    Veroslav

Similar Threads

  1. 7cs alternatives
    By mcosta in forum Qt Programming
    Replies: 0
    Last Post: 20th June 2011, 13:41
  2. Design opinions needed
    By scott_hollen in forum Newbie
    Replies: 6
    Last Post: 24th February 2011, 00:44
  3. Thread design advice needed
    By jonks in forum Qt Programming
    Replies: 3
    Last Post: 22nd October 2009, 21:32
  4. Alternatives for Phonon ?
    By dano in forum Qt Programming
    Replies: 10
    Last Post: 31st August 2009, 11:19
  5. Design suggestions
    By vermarajeev in forum Qt Programming
    Replies: 1
    Last Post: 15th December 2006, 09:22

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.