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. Pro and cons about creating QObjects components on the stack instead of creating them dynamically.

Pro and cons about creating QObjects components on the stack instead of creating them dynamically.

Scheduled Pinned Locked Moved Solved General and Desktop
24 Posts 5 Posters 3.2k 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.
  • kshegunovK kshegunov

    @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

    @jsulm Thanks, which is the best approach in the qt environment to prevent leaks caused by a dynamic allocated qobject without ownership before it has assigned to a father.

    The best way is to declare the ownership explicitly. Assuming that code resides in a QWidget:

    toolbar = new QToolBar(this);
    if (wrong)  {
        toolbar->deleteLater();
        toolbar = nullptr;
        return;
    }
    

    If this is in some outside class, you can do this:

    QScopedPointer<QToolBar> toolbar(new QToolBar());
    if (wrong)
        return;
    
    widget->addToolBar(toolbar.take());
    
    JonBJ Online
    JonBJ Online
    JonB
    wrote on last edited by JonB
    #7

    @kshegunov
    You haven't commented on my sugegstion, which probably means you don't like it but are too kind to me to say so ;-)

    The question, as I read/think of it, is: Imagine I have a big function, with the new QToolbar at the top and lots of (potential) returns dotted all over the place, with the final addToolbar() near the end. I do not want to manually put in my own delete/deleteLater()s prior to the returns, because I'll make a mistake.

    In that case, wouldn't my suggestion of a "temporary stack-based parent till the addToolbar() call" be a simple way of ensuring a newed QToolbar gets deleted on function scope exit be acceptable?

    kshegunovK Jimmy LoyolaJ 2 Replies Last reply
    1
    • JonBJ JonB

      @kshegunov
      You haven't commented on my sugegstion, which probably means you don't like it but are too kind to me to say so ;-)

      The question, as I read/think of it, is: Imagine I have a big function, with the new QToolbar at the top and lots of (potential) returns dotted all over the place, with the final addToolbar() near the end. I do not want to manually put in my own delete/deleteLater()s prior to the returns, because I'll make a mistake.

      In that case, wouldn't my suggestion of a "temporary stack-based parent till the addToolbar() call" be a simple way of ensuring a newed QToolbar gets deleted on function scope exit be acceptable?

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

      @JonB said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

      You haven't commented on my sugegstion, which probably means you don't like it but are too kind to me to say so ;-)

      I don't like it, I'm saying so.

      The question, as I read/think of it, is: Imagine I have a big function, with the new QToolbar at the top and lots of (potential) returns dotted all over the place. I do not want to manually put in my own delete/deleteLater()s prior to the returns, because I'll make a mistake.

      Yes, that's a valid concern. Then you'd use a scoped pointer so you make sure you own that object all the way until you actually add it to a container widget (i.e. a toolbar in this case)

      In that case, wouldn't my suggestion of a "temporary stack-based parent till the addToolbar() call" be a simple way of ensuring a newed QToolbar gets deleted on function scope exit be acceptable?

      Yes, although I'd avoid creating the heavy (compared to an owing pointer) machinery that is a widget just to ensure an object is deleted, hence me not liking it - it's an abuse of notation so to speak. There are better and "lighter" ways to do it, as I've mentioned.

      Read and abide by the Qt Code of Conduct

      JonBJ 1 Reply Last reply
      2
      • kshegunovK kshegunov

        @JonB said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

        You haven't commented on my sugegstion, which probably means you don't like it but are too kind to me to say so ;-)

        I don't like it, I'm saying so.

        The question, as I read/think of it, is: Imagine I have a big function, with the new QToolbar at the top and lots of (potential) returns dotted all over the place. I do not want to manually put in my own delete/deleteLater()s prior to the returns, because I'll make a mistake.

        Yes, that's a valid concern. Then you'd use a scoped pointer so you make sure you own that object all the way until you actually add it to a container widget (i.e. a toolbar in this case)

        In that case, wouldn't my suggestion of a "temporary stack-based parent till the addToolbar() call" be a simple way of ensuring a newed QToolbar gets deleted on function scope exit be acceptable?

        Yes, although I'd avoid creating the heavy (compared to an owing pointer) machinery that is a widget just to ensure an object is deleted, hence me not liking it - it's an abuse of notation so to speak. There are better and "lighter" ways to do it, as I've mentioned.

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #9

        @kshegunov Good stuff, point taken, thanks for letting me down gently ;-)

        1 Reply Last reply
        3
        • kshegunovK kshegunov

          @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

          @jsulm Thanks, which is the best approach in the qt environment to prevent leaks caused by a dynamic allocated qobject without ownership before it has assigned to a father.

          The best way is to declare the ownership explicitly. Assuming that code resides in a QWidget:

          toolbar = new QToolBar(this);
          if (wrong)  {
              toolbar->deleteLater();
              toolbar = nullptr;
              return;
          }
          

          If this is in some outside class, you can do this:

          QScopedPointer<QToolBar> toolbar(new QToolBar());
          if (wrong)
              return;
          
          widget->addToolBar(toolbar.take());
          
          Jimmy LoyolaJ Offline
          Jimmy LoyolaJ Offline
          Jimmy Loyola
          wrote on last edited by
          #10

          @kshegunov Thank you, its a little bit unusual listening about that heap allocation is more secure than stack allocation for memory management. But if this is the qt philosophy we must follow it.

          kshegunovK 1 Reply Last reply
          0
          • Jimmy LoyolaJ Jimmy Loyola

            @kshegunov Thank you, its a little bit unusual listening about that heap allocation is more secure than stack allocation for memory management. But if this is the qt philosophy we must follow it.

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

            @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

            its a little bit unusual listening about that heap allocation is more secure than stack allocation for memory management. But if this is the qt philosophy we must follow it.

            I didn't say that, in fact I argued that both are valid approaches. As you can leak or double-delete a heap object, so you can double delete a stack object, it's just a fact of life. In any case Qt allows you both gracefully, so it's up to your preference which you're going to use. Me personally, I'm a stack-lover, I always put things in the stack if I can help it. It usually looks something like this:

            class Dummy : public QObject
            {
            public:
                using QObject::QObject;
            };
            
            class DummyParent : public QObject
            {
            public:
                DummyParent(QObject * parent = nullptr)
                    : QObject(parent), owned(this)
                {
                }
            
                Dummy owned;
            };
            

            This construct is a FILO (i.e. stack) by itself, so it works gloriously without an issue.

            Read and abide by the Qt Code of Conduct

            Jimmy LoyolaJ 2 Replies Last reply
            2
            • JonBJ JonB

              @kshegunov
              You haven't commented on my sugegstion, which probably means you don't like it but are too kind to me to say so ;-)

              The question, as I read/think of it, is: Imagine I have a big function, with the new QToolbar at the top and lots of (potential) returns dotted all over the place, with the final addToolbar() near the end. I do not want to manually put in my own delete/deleteLater()s prior to the returns, because I'll make a mistake.

              In that case, wouldn't my suggestion of a "temporary stack-based parent till the addToolbar() call" be a simple way of ensuring a newed QToolbar gets deleted on function scope exit be acceptable?

              Jimmy LoyolaJ Offline
              Jimmy LoyolaJ Offline
              Jimmy Loyola
              wrote on last edited by
              #12

              @JonB I liked your answer too much. I forgot to say that in some cases I could have objects that couldn't have a parent like a toolbar or other qt starndard objects. In that case I can't give them a temporary parent.

              1 Reply Last reply
              0
              • kshegunovK kshegunov

                @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                its a little bit unusual listening about that heap allocation is more secure than stack allocation for memory management. But if this is the qt philosophy we must follow it.

                I didn't say that, in fact I argued that both are valid approaches. As you can leak or double-delete a heap object, so you can double delete a stack object, it's just a fact of life. In any case Qt allows you both gracefully, so it's up to your preference which you're going to use. Me personally, I'm a stack-lover, I always put things in the stack if I can help it. It usually looks something like this:

                class Dummy : public QObject
                {
                public:
                    using QObject::QObject;
                };
                
                class DummyParent : public QObject
                {
                public:
                    DummyParent(QObject * parent = nullptr)
                        : QObject(parent), owned(this)
                    {
                    }
                
                    Dummy owned;
                };
                

                This construct is a FILO (i.e. stack) by itself, so it works gloriously without an issue.

                Jimmy LoyolaJ Offline
                Jimmy LoyolaJ Offline
                Jimmy Loyola
                wrote on last edited by
                #13

                @kshegunov Doesn't Dummy class have a constructor?

                1 Reply Last reply
                0
                • kshegunovK kshegunov

                  @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                  its a little bit unusual listening about that heap allocation is more secure than stack allocation for memory management. But if this is the qt philosophy we must follow it.

                  I didn't say that, in fact I argued that both are valid approaches. As you can leak or double-delete a heap object, so you can double delete a stack object, it's just a fact of life. In any case Qt allows you both gracefully, so it's up to your preference which you're going to use. Me personally, I'm a stack-lover, I always put things in the stack if I can help it. It usually looks something like this:

                  class Dummy : public QObject
                  {
                  public:
                      using QObject::QObject;
                  };
                  
                  class DummyParent : public QObject
                  {
                  public:
                      DummyParent(QObject * parent = nullptr)
                          : QObject(parent), owned(this)
                      {
                      }
                  
                      Dummy owned;
                  };
                  

                  This construct is a FILO (i.e. stack) by itself, so it works gloriously without an issue.

                  Jimmy LoyolaJ Offline
                  Jimmy LoyolaJ Offline
                  Jimmy Loyola
                  wrote on last edited by
                  #14

                  @kshegunov I'm a stack-lover too so I'am traying to learn how to manage qt stacked objects properly. Could you link some good documentation about this topic? I would be glad. I see even qt recommend use dynamic memory to allocate gui objects but its docs doesn't specify how to deal with potential problems of this approach in a detailed way.

                  kshegunovK 1 Reply Last reply
                  0
                  • Jimmy LoyolaJ Jimmy Loyola

                    @kshegunov I'm a stack-lover too so I'am traying to learn how to manage qt stacked objects properly. Could you link some good documentation about this topic? I would be glad. I see even qt recommend use dynamic memory to allocate gui objects but its docs doesn't specify how to deal with potential problems of this approach in a detailed way.

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

                    @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                    I'm a stack-lover too so I'am traying to learn how to manage qt stacked objects properly. Could you link some good documentation about this topic?

                    Not currently, but I'll try to muster something this evening. In the mean time the major rule is - make sure the child is freed (by the stack) before the parent, this is enough. Also be wary of ownership transfer in Qt (it's noted in the docs).

                    I would be glad. I see even qt recommend use dynamic memory to allocate gui objects but its docs doesn't specify how to deal with potential problems of this approach in a detailed way.

                    I wouldn't go as far as to say it "recommends" it, but yes, it's more usual.

                    Read and abide by the Qt Code of Conduct

                    Jimmy LoyolaJ 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                      I'm a stack-lover too so I'am traying to learn how to manage qt stacked objects properly. Could you link some good documentation about this topic?

                      Not currently, but I'll try to muster something this evening. In the mean time the major rule is - make sure the child is freed (by the stack) before the parent, this is enough. Also be wary of ownership transfer in Qt (it's noted in the docs).

                      I would be glad. I see even qt recommend use dynamic memory to allocate gui objects but its docs doesn't specify how to deal with potential problems of this approach in a detailed way.

                      I wouldn't go as far as to say it "recommends" it, but yes, it's more usual.

                      Jimmy LoyolaJ Offline
                      Jimmy LoyolaJ Offline
                      Jimmy Loyola
                      wrote on last edited by Jimmy Loyola
                      #16

                      @kshegunov said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                      make sure the child is freed (by the stack) before the parent

                      What do you thinkg about make sure the children are freed before their parents in the all application classes could require big efforts?

                      JonBJ kshegunovK 2 Replies Last reply
                      0
                      • Jimmy LoyolaJ Jimmy Loyola

                        @kshegunov said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                        make sure the child is freed (by the stack) before the parent

                        What do you thinkg about make sure the children are freed before their parents in the all application classes could require big efforts?

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by
                        #17

                        @Jimmy-Loyola
                        @kshegunov is talking about "freed by the stack". That just means scope exit for local variables. So long as you add stack children after parent, not set parent on a child, this is the natural way function calls will arrange, is it not?

                        Jimmy LoyolaJ 1 Reply Last reply
                        0
                        • Jimmy LoyolaJ Jimmy Loyola

                          @kshegunov said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                          make sure the child is freed (by the stack) before the parent

                          What do you thinkg about make sure the children are freed before their parents in the all application classes could require big efforts?

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

                          @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                          What do you thinkg about make sure the children are freed before their parents in the all application classes could require big efforts?

                          Not really. If you stick to the "child is a member of parent object" (as I'd shown) you wouldn't have much trouble. Still caution is advised if objects are given to Qt for say to be inserted in a tab widget, because usually these containers take ownership of the object you pass them.

                          @JonB said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                          @kshegunov is talking about "freed by the stack". That just means scope exit for local variables. So long as you add stack children after parent, not set parent on a child, this is the natural way function calls will arrange, is it not?

                          Quite correct, yes. So like this:

                          QObject parent(nullptr); // Root object, no parent
                          QObject child1(&parent);
                          QObject child2(&child1);
                          

                          By the natural way the stack is constructed you destroy them backwards, so you always destroy the children before the parent and you're perfectly fine. Compare with:

                          QObject child1(nullptr); // Why no parent if it's a child
                          QObject parent(nullptr); // First to go out of scope, the bells should be ringing in your ears already
                          child.setParent(&parent); // Oh, no, no, I didn't mean to break the stack when we exit ...
                          

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          4
                          • JonBJ JonB

                            @Jimmy-Loyola
                            @kshegunov is talking about "freed by the stack". That just means scope exit for local variables. So long as you add stack children after parent, not set parent on a child, this is the natural way function calls will arrange, is it not?

                            Jimmy LoyolaJ Offline
                            Jimmy LoyolaJ Offline
                            Jimmy Loyola
                            wrote on last edited by
                            #19

                            @JonB Right, the last one thing, why should I set a parent to a stacked QObject if I don't want that qt manages memory for it?
                            I mean, if I never set a parent for stacked qobject the order of the objects creation doesn't matter because they aren't in the qt object tree. I am right or not? Thanks

                            JonBJ kshegunovK 2 Replies Last reply
                            0
                            • Jimmy LoyolaJ Jimmy Loyola

                              @JonB Right, the last one thing, why should I set a parent to a stacked QObject if I don't want that qt manages memory for it?
                              I mean, if I never set a parent for stacked qobject the order of the objects creation doesn't matter because they aren't in the qt object tree. I am right or not? Thanks

                              JonBJ Online
                              JonBJ Online
                              JonB
                              wrote on last edited by JonB
                              #20

                              @Jimmy-Loyola
                              Yes, that in itself is true, if you have stack variables with no parentage it won't matter about destruction order.

                              But as per @kshegunov code, in order to use these objects your code may have to set up parentage (or call Qt functions which implicitly do) as it goes along, and then the order will matter.

                              1 Reply Last reply
                              0
                              • Jimmy LoyolaJ Jimmy Loyola

                                @JonB Right, the last one thing, why should I set a parent to a stacked QObject if I don't want that qt manages memory for it?
                                I mean, if I never set a parent for stacked qobject the order of the objects creation doesn't matter because they aren't in the qt object tree. I am right or not? Thanks

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

                                In addition to what @JonB wrote, the object trees are not exclusively for memory management. The widgets use the parent as a visual parent as well, and to distinguish between needing to be an alien or a native widget.

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                0
                                • S Offline
                                  S Offline
                                  SimonSchroeder
                                  wrote on last edited by
                                  #22

                                  @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                                  I mean, if I never set a parent for stacked qobject the order of the objects creation doesn't matter because they aren't in the qt object tree. I am right or not? Thanks

                                  If you were to really do that, then you are fine. However, there is a slightly non-obvious way of setting a parent: When you put a widget into a layout it is re-parented. (And so its lifetime is again managed by Qt.) Basically the best rule you can have is that in general widgets should live on the heap. There are very few exceptions for this: 1) The MainWindow created in main can live on the stack (it does not have a parent). 2) A modal dialog can usually be constructed on the stack.

                                  As mentioned before, all the other non-widget class, e.g. QFile, can be managed without parents and thus are allowed to live on the stack.

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • S SimonSchroeder

                                    @Jimmy-Loyola said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                                    I mean, if I never set a parent for stacked qobject the order of the objects creation doesn't matter because they aren't in the qt object tree. I am right or not? Thanks

                                    If you were to really do that, then you are fine. However, there is a slightly non-obvious way of setting a parent: When you put a widget into a layout it is re-parented. (And so its lifetime is again managed by Qt.) Basically the best rule you can have is that in general widgets should live on the heap. There are very few exceptions for this: 1) The MainWindow created in main can live on the stack (it does not have a parent). 2) A modal dialog can usually be constructed on the stack.

                                    As mentioned before, all the other non-widget class, e.g. QFile, can be managed without parents and thus are allowed to live on the stack.

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

                                    @SimonSchroeder said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                                    Basically the best rule you can have is that in general widgets should live on the heap.

                                    Why do you do this to me? I just spent 2 days and about 7 posts to show there's no such rule. If there's such a recommendation even, that is to avoid putting objects in the stack, in the Qt documentation please point me to it.

                                    Read and abide by the Qt Code of Conduct

                                    1 Reply Last reply
                                    1
                                    • S Offline
                                      S Offline
                                      SimonSchroeder
                                      wrote on last edited by
                                      #24

                                      @kshegunov said in Pro and cons about creating QObjects components on the stack instead of creating them dynamically.:

                                      Why do you do this to me? I just spent 2 days and about 7 posts to show there's no such rule. If there's such a recommendation even, that is to avoid putting objects in the stack, in the Qt documentation please point me to it.

                                      You are right that it is nowhere written in the Qt documentation. And this is only a rule of thumb. As you have showed it is possible to put them on the stack. However, in most cases you do not have widgets living inside the scope of a function. In many cases I construct widgets inside the constructor of another widget's class. (Right now, I don't even use member variables because the parent tree will take care of everything.) In this case I would need a bunch of member variables inside the class. These would need to be in the right order inside the class declaration already (because they are initialized in that order). I think it is hard to add just another widget in the right place in this list of members (and beware if you forget to think about it only once). BTW, I am not even entirely sure how the widget will be re-parented when added to a layout. Is it reparented to the layout or the widget that the layout belongs to?

                                      In short: If you put your widgets on the heap and you are consistently using layouts, you don't have to think about anything at all. You don't even have to think about setting parents. If, on the other hand, you are putting your widgets on the stack you always have to take care of the order of variable declarations. You need to think about two things at the same time: The look of your UI and memory management/stack layout. Adding a new widget to the layout is harder because you need to find the right place to declare it. Moving a widget to another place in your layout could mean to move its declaration as well if you are using sublayouts.

                                      To me, it is much harder to reason about widgets on the stack. And it certainly is not beginner-friendly. It might even become a maintenaince nightmare. I usually try to use approaches that have the least chance of accidental errors. That is why I usually put everything I can on the stack. Then I get free lifetime management. The Qt parent tree also manages lifetime. Having two competing lifetime managers is just too error prone. I don't want to fight Qt's lifetime manager, but rather be friends with it.

                                      The only reason left to not put widgets on the heap would be speed. new and delete are notoriously slow. Nevertheless, we are talking about the GUI here and thus only have to match human speed. I have rarely seen a performance problem with creating layouted widgets fully on the heap. So, as long as you don't have a performance problem don't optimize prematurely.

                                      Basically, what it comes down to why I am proposing allocation of widgets on the heap as a rule of thumb is 1) maintainability and 2) saving hours of debugging mysterious errors.

                                      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