Results 1 to 5 of 5

Thread: Parent deleting children in a derived class

  1. #1
    Join Date
    Feb 2013
    Posts
    71
    Thanks
    6
    Thanked 3 Times in 3 Posts
    Platforms
    Windows

    Question Parent deleting children in a derived class

    Say we have a custom Widget that looks something along the lines of:

    Qt Code:
    1. class Test : public QWidget
    2. {
    3. public:
    4. Test(QWidget *parent = nullptr) : QWidget(parent) , label(new QLabel(tr("Hello")))
    5. {
    6. QHBoxLayout *layout = new QHBoxLayout;
    7. layout->addWidget( label );
    8. setLayout( layout ); //add the current layout and widgets to be children to this(Test)
    9. }
    10. ~Test(void){}
    11. private:
    12. QLabel *label;
    13. };
    To copy to clipboard, switch view to plain text mode 


    What I am concerned about is memory leaking from label or layout when I delete a parent (Test) object. I tried something like:
    Qt Code:
    1. ~Test( void ) { if( label ) std::cerr << "Label was not destroyed!" << std::endl; }
    To copy to clipboard, switch view to plain text mode 
    and the output was not what I was hoping for could this be due to me mistaking what they mean by being a parent/child or does it delete them in some random order?

    Also when we have nested layouts and we destroy the parent layout are the children layouts automatically deleted also?

    Something like:

    Qt Code:
    1. QHBoxLayout *layout1 = new QHBoxLayout;
    2. QVBoxLayout *layout2 = new QVBoxLayout;
    3. layout2->addLayout(layout1);
    4.  
    5. //if layout2 is deleted is layout1 also?
    To copy to clipboard, switch view to plain text mode 

    I am used to having to manually delete heap stuff or the use of RAII not the object tree way. Thanks for any help I greatly appreciate it.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Parent deleting children in a derived class

    The child objects will be deleted when the QObject destructor runs, which will occur after the derived class destructor does. The children are directly deleted at that time, i.e. QObject::deleteLater() is not used. At the point you inspect the value of label it has not been destroyed. (Deleting the label would not reset the value of the pointer to 0 in any case, so your test is not a good one.)

    A child layout added to another layout is given the parent layout as its parent. Widgets that layouts control are parented to the widget that the top-most layout is associated with. They typically are all destroyed automatically when the owning widget is destroyed.

    Inspect the output of this to see the order of things
    Qt Code:
    1. #include <QApplication>
    2. #include <QVBoxLayout>
    3. #include <QWidget>
    4. #include <QTimer>
    5. #include <QDebug>
    6.  
    7. class InstrumentedWidget: public QWidget
    8. {
    9. Q_OBJECT
    10. public:
    11. InstrumentedWidget(QWidget *p = 0): QWidget(p) {
    12. qDebug() << "Construct" << this;
    13. }
    14. ~InstrumentedWidget() {
    15. qDebug() << "Destroy" << this << this->parent();
    16. }
    17. };
    18.  
    19. class InstrumentedVBox: public QVBoxLayout
    20. {
    21. Q_OBJECT
    22. public:
    23. InstrumentedVBox(QWidget *p = 0): QVBoxLayout(p) {
    24. qDebug() << "Construct" << this;
    25. }
    26. ~InstrumentedVBox() {
    27. qDebug() << "Destroy" << this << this->parent();
    28. }
    29. };
    30.  
    31. int main(int argc, char **argv) {
    32. QApplication app(argc, argv);
    33.  
    34. InstrumentedWidget mw;
    35.  
    36. InstrumentedVBox *outer = new InstrumentedVBox;
    37. outer->addWidget(new InstrumentedWidget);
    38. outer->addWidget(new InstrumentedWidget);
    39.  
    40. InstrumentedVBox *inner = new InstrumentedVBox;
    41. inner->addWidget(new InstrumentedWidget);
    42. inner->addWidget(new InstrumentedWidget);
    43. outer->addLayout(inner);
    44.  
    45. mw.setLayout(outer);
    46.  
    47. qDebug() << "Waiting a second";
    48. QTimer::singleShot(1000, &app, SLOT(quit()));
    49. return app.exec();
    50. // mw will be destroyed here
    51. }
    52. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to ChrisW67 for this useful post:

    giblit (4th March 2014)

  4. #3
    Join Date
    Feb 2013
    Posts
    71
    Thanks
    6
    Thanked 3 Times in 3 Posts
    Platforms
    Windows

    Default Re: Parent deleting children in a derived class

    Deleting the label would not reset the value of the pointer to 0 in any case, so your test is not a good one.
    Was thinking that the QObject destructor would delete it then assign it as a nullptr for some odd reason.

    Thanks for your example I see how it works now. It just felt weird creating objects on the heap without RAII and them being deleted automatically.

  5. #4
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Parent deleting children in a derived class

    If You want to auto-reset pointer after object deleting use QPointer. From QPointer doc : A guarded pointer, QPointer<T>, behaves like a normal C++ pointer T *, except that it is automatically set to 0 when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases)

  6. The following user says thank you to Lesiok for this useful post:

    giblit (4th March 2014)

  7. #5
    Join Date
    Feb 2013
    Posts
    71
    Thanks
    6
    Thanked 3 Times in 3 Posts
    Platforms
    Windows

    Default Re: Parent deleting children in a derived class

    Thanks. I didn't know that.

Similar Threads

  1. Deleting rows (children) from a qstandarditem
    By Valheru in forum Qt Programming
    Replies: 4
    Last Post: 29th March 2012, 17:04
  2. Deleting children of a widget
    By ComServant in forum Newbie
    Replies: 5
    Last Post: 7th October 2011, 01:09
  3. Deleting a QWidget derived object manually
    By hubbobubbo in forum Qt Programming
    Replies: 2
    Last Post: 4th February 2010, 17:32
  4. Replies: 2
    Last Post: 7th December 2006, 00:41
  5. Signal/slot looking in base class, not derived class
    By georgie in forum Qt Programming
    Replies: 2
    Last Post: 12th May 2006, 08:36

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.