Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSharedPointer Deleter
Forum Updated to NodeBB v4.3 + New Features

QSharedPointer Deleter

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 6.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    brauni
    wrote on last edited by
    #1

    Hi everyone.
    I have a little trouble with using QSharedPointer.

    I dont found solution nor in google nor at this forum, thereby I start new theme.

    Problem:

    I have class Cipher. Object of this class produced by Factory, and return to user wrapped in QSharedPointer. Only Factory may produce this object, and only QSharedPointer may delete them.

    For this reason I declare class this way:
    @
    class Cipher : public QObject
    {
    friend class Factory;
    friend class QSharedPointer;

    public:
    ...
    protected:
    Cipher()
    {};
    virtual ~Cipher()
    {};
    };
    @

    But I get error during compilation, because destructor is protected.

    Adding following declaration resolve this problem:
    @template <class T> friend class QtSharedPointer::ExternalRefCount;@

    But QtSharedPointer::ExternalRefCount hide from user and cannot be found in documentation. Thereby this solution is dirty hack and cannot be used.

    After that I found deleter parameter in QSharedPointer constructor. Unfortunatelly Assistant don have enought documentation. I was leaded by intuition :) I modify class:
    @
    class Cipher : public QObject
    {
    friend class QSharedPointer;

    public:
    ...
    protected:

    static void myDeleter(Cipher *obj)
    {
        delete obj;
    }
    
    Cipher()
    {};
    virtual ~Cipher()
    {};
    

    };
    @
    And call in factory following constructor:
    @QSharedPointer <Cipher>result(temporary, &Cipher::myDeleter)@
    But I recieve the same error. Declaring myDeleter as public dont resolve problem.

    Then I start reading source code of QSharedPointer and find this function:
    @static inline void deref(Data *d, T *value)
    {
    if (!d) return;
    if (!d->strongref.deref()) {
    if (!d->destroy())
    delete value;
    }
    if (!d->weakref.deref())
    delete d;
    }@
    Here Value is pointer to Cipher object. And deleter function is called in @d->destroy()@
    So I decide that QSharedPointer can not work with private destructor.

    Finally I have some questions.

    1. Can I use QSharedPointer with classes with private destructor?
    2. How can I deny deleting Cipher object to everyone except QSharedPointer?
    3. Who have complete documentation about deleter?
      4 Is this bug or feature?
    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #2

      bq. 2. How can I deny deleting Cipher object to everyone except QSharedPointer?

      You can't. If someone holds a cipher object by it's base class pointer (QObject*) the he can delete it.

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Franzk
        wrote on last edited by
        #3

        Since Cipher is a QObject, it will emit a destroyed() signal. If there is a possibility that the Cipher is being destroyed without your classes knowing about it, you should from my point of view be handling the destroyed() signal, rather than trying to prevent users from deleting the thing.

        "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #4

          Using a QPOinter could help, as it goes to 0 if the object behind is deleted. Then you only have to handle pointer != 0.

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • F Offline
            F Offline
            Franzk
            wrote on last edited by
            #5

            [quote author="Gerolf" date="1307522156"]Using a QPOinter could help, as it goes to 0 if the object behind is deleted. Then you only have to handle pointer != 0.[/quote]
            And since QPointer is deprecated since Qt 4.6, you should use QWeakPointer. It does exactly the same and is said to be slightly safer.

            "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0
            • B Offline
              B Offline
              brauni
              wrote on last edited by
              #6

              [quote author="Gerolf" date="1307522156"]Using a QPOinter could help, as it goes to 0 if the object behind is deleted. Then you only have to handle pointer != 0.[/quote]

              I will look at this class.

              It is not important that Cipher is inherited from QObject. I can modify class and remove this inheritence. Sorry that I dont describe this. Of course user can remove Cipher with pointer to QObject class.

              What about this classes:
              @class Cipher
              {
              friend class Factory;

              public:
              ...
              protected:
              Cipher()
              {}
              virtual ~Cipher()
              {}
              };

              class Factory
              {
              public:
              static QSharedPointer<Cipher> create()
              {
              return QSharedPointer<Cipher>(new Cipher);
              }
              };
              @

              What I need add to this definition for guarantee that only QSharedPointer can destroy Cipher object. Without @template <class T> friend class QtSharedPointer::ExternalRefCount;@

              I have some places in my project with seems trouble. Really I can kick out this check, but it is very interesting task, and I wand to find solution.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved