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. How to handle failures on construction?

How to handle failures on construction?

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 2.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.
  • Steve7b1S Offline
    Steve7b1S Offline
    Steve7b1
    wrote on last edited by A Former User
    #1

    Hi,

    I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

    class X: public QWidget
    {
    public:
        X() : QWidget(nullptr)
        {
            QPushButton * b = new QPushButton ;
            b->setParent(this) ;
    
             // suppose something down here throws...
        }
    }
    
    // client code:
        X *x = nullptr  ;
        try
        {
            x = new X ;
        }
        catch (...) 
        {
            // ...
        }
    

    this is a simplified example with no layouts or anything, I guess the question boils down to whether or not the widget memory management cleanup for X will be called without a call to the destructor of X?

    [Edit: Added code tags -- @Wieland]

    kshegunovK 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Nothing cleans up without the call to the dtor.
      but if u do QPushButton * b = new QPushButton(this) ; (or setParent)
      Then X will be deleted and all children.
      If X has no parents, it might be issue.
      Its a system.
      http://doc.qt.io/qt-5/objecttrees.html

      Steve7b1S 1 Reply Last reply
      1
      • Steve7b1S Steve7b1

        Hi,

        I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

        class X: public QWidget
        {
        public:
            X() : QWidget(nullptr)
            {
                QPushButton * b = new QPushButton ;
                b->setParent(this) ;
        
                 // suppose something down here throws...
            }
        }
        
        // client code:
            X *x = nullptr  ;
            try
            {
                x = new X ;
            }
            catch (...) 
            {
                // ...
            }
        

        this is a simplified example with no layouts or anything, I guess the question boils down to whether or not the widget memory management cleanup for X will be called without a call to the destructor of X?

        [Edit: Added code tags -- @Wieland]

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

        @Steve7b1 said in How to handle failures on construction?:

        I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

        My advice - don't throw from the constructor. It's a bad habit in my opinion and you can easily go without it. As a side note Qt will not throw from the constructor, so any allocations you make are "safe".

        Read and abide by the Qt Code of Conduct

        Steve7b1S 1 Reply Last reply
        2
        • mrjjM mrjj

          Hi
          Nothing cleans up without the call to the dtor.
          but if u do QPushButton * b = new QPushButton(this) ; (or setParent)
          Then X will be deleted and all children.
          If X has no parents, it might be issue.
          Its a system.
          http://doc.qt.io/qt-5/objecttrees.html

          Steve7b1S Offline
          Steve7b1S Offline
          Steve7b1
          wrote on last edited by
          #4

          @mrjj Hi,

          Thanks for your reply; I don't understand though why the child would be cleaned up in the example I gave, because the destructor isn't being called if we throw from within the constructor... could you expand a little?

          Steve.

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi
            QPushButton * b is owned by class X

            so when X is deleted then the childs are deleted too.

            Often Class X is owned by main window or other toplevel parent.
            So when its deleted, Class X is freed and so is button b.

            But yes, if Class X have no parent and u throw in ctor. then you got a leak :)
            "It cannot die, for it never lived." Kinda situation which can be avoided by not throwing in ctor.

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              @Steve7b1 said in How to handle failures on construction?:

              I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

              My advice - don't throw from the constructor. It's a bad habit in my opinion and you can easily go without it. As a side note Qt will not throw from the constructor, so any allocations you make are "safe".

              Steve7b1S Offline
              Steve7b1S Offline
              Steve7b1
              wrote on last edited by
              #6

              @kshegunov Thanks for your reply. So would you suggest doing allocations with

              QWidget * p = new (std::nothrow) QWhatever(this) ;

              and then just checking the pointer value?

              Steve.

              kshegunovK 1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Steve7b1 Hi, do you have any condition in mind that would make one of your constructors throw an error ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                Steve7b1S 1 Reply Last reply
                1
                • SGaistS SGaist

                  @Steve7b1 Hi, do you have any condition in mind that would make one of your constructors throw an error ?

                  Steve7b1S Offline
                  Steve7b1S Offline
                  Steve7b1
                  wrote on last edited by
                  #8

                  @SGaist I am mostly concerned about allocation failures; rare, but possible. I work on a system which is to do with visualisation of large datasets. Most of my usage is related to QGraphicsView and QGraphicsScene (not much like the example I gave, that was just hypothetical).

                  Our users often leave sessions going for weeks, just closing their laptops and going home, so I have to maintain certain levels of paranoia...

                  1 Reply Last reply
                  0
                  • Steve7b1S Steve7b1

                    @kshegunov Thanks for your reply. So would you suggest doing allocations with

                    QWidget * p = new (std::nothrow) QWhatever(this) ;

                    and then just checking the pointer value?

                    Steve.

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

                    No, I suggest not throwing from the constructor (and ignoring the "out of memory" exception which you can do little to prevent). Also if you want to be throw-safe then don't use heap allocation (especially since in apps you're not concerned with binary compatibility). E.g.:

                    class X: public QWidget
                    {
                        Q_OBJECT  //< Don't forget this one
                    public:
                        X(QWidget * parent = nullptr)  //< Pass on the parent, don't work against the framework!
                            : QWidget(parent), b(this)
                        {
                             // Suppose something down here throws ...
                             // ... then the stack is automatically unrolled as per documented C++ behaviour
                        }
                    private:
                        QPushButton b; //< Can't get more throw-safe than this!
                    };
                    

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    1
                    • Steve7b1S Offline
                      Steve7b1S Offline
                      Steve7b1
                      wrote on last edited by
                      #10

                      OK, I understand your strategy; thanks for the advice.

                      Steve.

                      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