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. Should every class in Qt derive from QObject?

Should every class in Qt derive from QObject?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 4.4k Views
  • 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.
  • enemyofthedawnE Offline
    enemyofthedawnE Offline
    enemyofthedawn
    wrote on last edited by enemyofthedawn
    #1

    What if I don't need signals and slots in particular class and all I'm interested in is garbage collection? Should I go with non qt class instead and use just QSharedPointer or delete? That would eliminate the heaviness QObject inheritance adds.

    Let's say I have class that depends on another class for example Store and StoreItem. StoreItem constructor is defined as follows:

    StoreItem(Store *store)

    it has a member pointer to Store so you know to which store it belongs. The Store class has QVector<StoreItem*> or QVector<QSharedPointer<QStoreItem*>> inside and functions like StoreItem *addItem(...).

    Should StoreItem be a QObject class or non qt class?
    Should Store be a QObject class?

    What are general rules when to inherit QObject and when not?

    A JKSHJ 2 Replies Last reply
    0
    • enemyofthedawnE enemyofthedawn

      What if I don't need signals and slots in particular class and all I'm interested in is garbage collection? Should I go with non qt class instead and use just QSharedPointer or delete? That would eliminate the heaviness QObject inheritance adds.

      Let's say I have class that depends on another class for example Store and StoreItem. StoreItem constructor is defined as follows:

      StoreItem(Store *store)

      it has a member pointer to Store so you know to which store it belongs. The Store class has QVector<StoreItem*> or QVector<QSharedPointer<QStoreItem*>> inside and functions like StoreItem *addItem(...).

      Should StoreItem be a QObject class or non qt class?
      Should Store be a QObject class?

      What are general rules when to inherit QObject and when not?

      A Offline
      A Offline
      ambershark
      wrote on last edited by
      #2

      @enemyofthedawn If I'm not going to use signals/slots in the class then I don't inherit from QObject.

      Then if I need something from QObject later I just add it in. So if I find I need a signal/slot all of a sudden I'll just modify the class to be derived from QObject.

      Those are my general rules while coding, but you can make your own based on how you feel. In the end it doesn't have much impact. :)

      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

      1 Reply Last reply
      4
      • enemyofthedawnE enemyofthedawn

        What if I don't need signals and slots in particular class and all I'm interested in is garbage collection? Should I go with non qt class instead and use just QSharedPointer or delete? That would eliminate the heaviness QObject inheritance adds.

        Let's say I have class that depends on another class for example Store and StoreItem. StoreItem constructor is defined as follows:

        StoreItem(Store *store)

        it has a member pointer to Store so you know to which store it belongs. The Store class has QVector<StoreItem*> or QVector<QSharedPointer<QStoreItem*>> inside and functions like StoreItem *addItem(...).

        Should StoreItem be a QObject class or non qt class?
        Should Store be a QObject class?

        What are general rules when to inherit QObject and when not?

        JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by JKSH
        #3

        @enemyofthedawn said in Should every class in Qt derive from QObject?:

        What if I don't need signals and slots in particular class and all I'm interested in is garbage collection?

        You don't need QObject for garbage collection. Use std::unique_ptr for a non-copyable non-sharable class, or std::shared_ptr for a copyable sharable class.

        [EDIT: Sorry, I meant "shareable", not "copyable". Here, allowing an object to be "shared" means allowing multiple entities to store pointers to the same object. --JKSH]

        What are general rules when to inherit QObject and when not?

        If you want signals and slots or any of the features described in http://doc.qt.io/qt-5/metaobjects.html, consider inheriting QObject. If you don't want any of those features, don't inherit QObject.

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        kshegunovK 1 Reply Last reply
        5
        • JKSHJ JKSH

          @enemyofthedawn said in Should every class in Qt derive from QObject?:

          What if I don't need signals and slots in particular class and all I'm interested in is garbage collection?

          You don't need QObject for garbage collection. Use std::unique_ptr for a non-copyable non-sharable class, or std::shared_ptr for a copyable sharable class.

          [EDIT: Sorry, I meant "shareable", not "copyable". Here, allowing an object to be "shared" means allowing multiple entities to store pointers to the same object. --JKSH]

          What are general rules when to inherit QObject and when not?

          If you want signals and slots or any of the features described in http://doc.qt.io/qt-5/metaobjects.html, consider inheriting QObject. If you don't want any of those features, don't inherit QObject.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @JKSH said in Should every class in Qt derive from QObject?:

          Use std::unique_ptr for a non-copyable class, or std::shared_ptr for a copyable class.

          I would argue here. Use the stack whenever possible (especially since std::unique_ptr is a stack object managing a heap allocation) and use either implicit or explicit sharing - QSharedDataPointer with QSharedData - for data classes (i.e. most of the stuff that falls into "copyable classes). std::shared_ptr and the Qt equivalent has the purpose of sharing a pointer, hence the name, not to share the object/data, which is a rather rare use case. Think of what happens when you start passing shared pointers around in say a multithreaded context ... you're basically guaranteeing you're going to blow your leg off ...

          Read and abide by the Qt Code of Conduct

          JKSHJ 1 Reply Last reply
          5
          • kshegunovK kshegunov

            @JKSH said in Should every class in Qt derive from QObject?:

            Use std::unique_ptr for a non-copyable class, or std::shared_ptr for a copyable class.

            I would argue here. Use the stack whenever possible (especially since std::unique_ptr is a stack object managing a heap allocation) and use either implicit or explicit sharing - QSharedDataPointer with QSharedData - for data classes (i.e. most of the stuff that falls into "copyable classes). std::shared_ptr and the Qt equivalent has the purpose of sharing a pointer, hence the name, not to share the object/data, which is a rather rare use case. Think of what happens when you start passing shared pointers around in say a multithreaded context ... you're basically guaranteeing you're going to blow your leg off ...

            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by JKSH
            #5

            @kshegunov said in Should every class in Qt derive from QObject?:

            @JKSH said in Should every class in Qt derive from QObject?:

            Use std::unique_ptr for a non-copyable class, or std::shared_ptr for a copyable class.

            I would argue here. Use the stack whenever possible (especially since std::unique_ptr is a stack object managing a heap allocation) and use either implicit or explicit sharing - QSharedDataPointer with QSharedData - for data classes (i.e. most of the stuff that falls into "copyable classes).

            Aargh, I used the wrong terminology. Rather than "copy" (as in copying the same data into multiple places and allowing each copy to be independently modified), I meant to say "share" (as in allowing multiple entities to store pointers to the same object).

            With @enemyofthedawn's example, StoreItem looks like an identity object rather than a data/value object (see http://doc.qt.io/qt-5/object.html#qt-objects-identity-vs-value ) which is why I suggested smart pointers as an alternative to QObject inheritance for memory management. Multiple Store objects each hold an array of StoreItem objects.

            If the owning Store is the only entity that reads/writes the StoreItems, then the array can be a QVector<std::unique_ptr<StoreItem>> (or std::vector). As @kshegunov highlighted, this can also be simply a QVector<StoreItem>. Either way, the memory occupied by StoreItem will be released once the owning Store is destroyed.

            If other objects are allowed to point to the same StoreItem, then the Store can hold a QVector<std::unique_ptr<StoreItem>> QVector<std::shared_ptr<StoreItem>> and expose std::shared_ptr<StoreItem> for other entities to access the items. This way, if the Store is destroyed while someone else is still accessing the StoreItem, the StoreItem will still remain usable until the last reader/writer is gone. (Although having said that, the StoreItem's internal Store pointer will no longer be valid, so this might be moot point)

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            enemyofthedawnE 1 Reply Last reply
            1
            • JKSHJ JKSH

              @kshegunov said in Should every class in Qt derive from QObject?:

              @JKSH said in Should every class in Qt derive from QObject?:

              Use std::unique_ptr for a non-copyable class, or std::shared_ptr for a copyable class.

              I would argue here. Use the stack whenever possible (especially since std::unique_ptr is a stack object managing a heap allocation) and use either implicit or explicit sharing - QSharedDataPointer with QSharedData - for data classes (i.e. most of the stuff that falls into "copyable classes).

              Aargh, I used the wrong terminology. Rather than "copy" (as in copying the same data into multiple places and allowing each copy to be independently modified), I meant to say "share" (as in allowing multiple entities to store pointers to the same object).

              With @enemyofthedawn's example, StoreItem looks like an identity object rather than a data/value object (see http://doc.qt.io/qt-5/object.html#qt-objects-identity-vs-value ) which is why I suggested smart pointers as an alternative to QObject inheritance for memory management. Multiple Store objects each hold an array of StoreItem objects.

              If the owning Store is the only entity that reads/writes the StoreItems, then the array can be a QVector<std::unique_ptr<StoreItem>> (or std::vector). As @kshegunov highlighted, this can also be simply a QVector<StoreItem>. Either way, the memory occupied by StoreItem will be released once the owning Store is destroyed.

              If other objects are allowed to point to the same StoreItem, then the Store can hold a QVector<std::unique_ptr<StoreItem>> QVector<std::shared_ptr<StoreItem>> and expose std::shared_ptr<StoreItem> for other entities to access the items. This way, if the Store is destroyed while someone else is still accessing the StoreItem, the StoreItem will still remain usable until the last reader/writer is gone. (Although having said that, the StoreItem's internal Store pointer will no longer be valid, so this might be moot point)

              enemyofthedawnE Offline
              enemyofthedawnE Offline
              enemyofthedawn
              wrote on last edited by enemyofthedawn
              #6

              @JKSH said in Should every class in Qt derive from QObject?:

              std::shared_ptr<StoreItem>

              I don't have to return std::shared_ptr<StoreItem> or QSharedPointer<StoreItem> as I'm fully aware that the owner of this object will exist when I access the item. What I do instead is simply returning pointer StoreItem* or just a reference StoreItem&.

              No?

              It's quite logical that Store is the owner of StoreItem and is responsible for freeing it and no one should ever desire to delete it outside of it

              What I would do instead is QVector<std::unique_ptr<StoreItem>> or maybe QVector<QScopedPointer<StoreItem>> and returning simple raw pointer with .get()

              My logic is when the store is destroyed all store items are destroyed with it.

              A 1 Reply Last reply
              0
              • enemyofthedawnE enemyofthedawn

                @JKSH said in Should every class in Qt derive from QObject?:

                std::shared_ptr<StoreItem>

                I don't have to return std::shared_ptr<StoreItem> or QSharedPointer<StoreItem> as I'm fully aware that the owner of this object will exist when I access the item. What I do instead is simply returning pointer StoreItem* or just a reference StoreItem&.

                No?

                It's quite logical that Store is the owner of StoreItem and is responsible for freeing it and no one should ever desire to delete it outside of it

                What I would do instead is QVector<std::unique_ptr<StoreItem>> or maybe QVector<QScopedPointer<StoreItem>> and returning simple raw pointer with .get()

                My logic is when the store is destroyed all store items are destroyed with it.

                A Offline
                A Offline
                ambershark
                wrote on last edited by
                #7

                @enemyofthedawn No, you definitely do not want to do that. The whole point of smart pointers like shared_ptr and unique_ptr is that they have reference counting so they can clean up for you. It's basically protecting you from having to deal with and track pointers.

                By ever passing the raw pointer you are pretty much removing all the benefit of smart pointers and potentially causing crashes. I.e. if you return a Store * from your shared_ptr<Store> object and something is using that when the shared_ptr goes out of scope, it will be deleted since it doesn't know about the Store * you sent out.

                If you have memory protected in a smart pointer then never use that outside the pointer unless you have a reference lock on it while you use the raw pointer. Returning a raw pointer would lose the reference since the shared_ptr would go out of scope.

                That felt like I was rambling lol. Hope that made it clearer for you. :)

                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                enemyofthedawnE 1 Reply Last reply
                2
                • A ambershark

                  @enemyofthedawn No, you definitely do not want to do that. The whole point of smart pointers like shared_ptr and unique_ptr is that they have reference counting so they can clean up for you. It's basically protecting you from having to deal with and track pointers.

                  By ever passing the raw pointer you are pretty much removing all the benefit of smart pointers and potentially causing crashes. I.e. if you return a Store * from your shared_ptr<Store> object and something is using that when the shared_ptr goes out of scope, it will be deleted since it doesn't know about the Store * you sent out.

                  If you have memory protected in a smart pointer then never use that outside the pointer unless you have a reference lock on it while you use the raw pointer. Returning a raw pointer would lose the reference since the shared_ptr would go out of scope.

                  That felt like I was rambling lol. Hope that made it clearer for you. :)

                  enemyofthedawnE Offline
                  enemyofthedawnE Offline
                  enemyofthedawn
                  wrote on last edited by
                  #8

                  @ambershark For std::shared_ptr yes. I was saying about std::unique_ptr from what I saw there's nothing wrong in returning raw pointer or reference with this type of smart pointer (see here)

                  A 1 Reply Last reply
                  1
                  • enemyofthedawnE enemyofthedawn

                    @ambershark For std::shared_ptr yes. I was saying about std::unique_ptr from what I saw there's nothing wrong in returning raw pointer or reference with this type of smart pointer (see here)

                    A Offline
                    A Offline
                    ambershark
                    wrote on last edited by ambershark
                    #9

                    @enemyofthedawn Oh yea that would be fine in unique_ptr. I must have misread that, I thought you were talking about shared_ptrs or moving them around outside of where they were created. I.e. using/storing them in a place that could have them cleaned up while still "in use".

                    My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                    1 Reply Last reply
                    2

                    • Login

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