How to handle failures on construction?
-
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]
-
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 -
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]
@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".
-
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 -
Hi
QPushButton * b is owned by class Xso 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. -
@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".
@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.
-
@Steve7b1 Hi, do you have any condition in mind that would make one of your constructors throw an error ?
@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...
-
@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.
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! };