[solved] What's better, Object instances or pointer to objects using 'new' statement ?



  • Since I'm reading documentation and other people's code I very often noticed that they create widgets as a pointer to an object instance using the 'new' statement. Creating a QPushButton then translates to this code:
    @QPushButton *my_psh_btn = new QPushButton(&parent_window);
    my_psh_btn->show();@

    Instead I've been always creating widgets by creating an object of some class:
    @QPushButton my_psh_btn(&parent_window);
    my_psh_btn.show();@

    Basically, the do the very same thing and it only changes the way you access the object methods, via a pointer or directly through the object itself. But is there any reason I should prefer using a pointer to an object instance (using 'new' statement) instead of an object instance itself? Maybe some reason related to Qt only?


  • Moderators

    Hi,

    Using new (called "allocating on the heap") is safer. It is possible to cause crashes if you do it the other way (called "allocating on the stack").

    This is because when you set a parent, the parent becomes responsible for deleting the child object. However, stack-allocated objects also have their destructor called when they go out of scope. Under certain conditions, stack-allocated QObjects that have parents will have their destructor called twice, causing a crash.

    Read http://qt-project.org/doc/qt-5.1/qtcore/objecttrees.html for more details.

    Another benefit of heap-allocation is the ability to use "forward declarations":http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml, which minimizes the number of #include's in your headers. For a large project, this significantly improves compilation speed.



  • That was very helpful, thanks!



  • As far as I understood QObject's destructor code, the parent will know that the object has already been deleted, and will not delete it a second time.

    In GraphicsView (which has a comparable parent-child auto-delete feature), I often explicitly delete objects that have a parent, because I want to achieve a certain order of termination.

    So far, no crashes, despite using this technique for months, and having dozens of auto-tests running on that code...



  • Not just safer to allocate on the heap, but trying to allocate everything on the stack is (with bigger programs) not possible. The stack size is limited and also every thread has it's own. while the heap a large chunk is provided by the OS and increased if needed. Using new is better.


  • Moderators

    [quote author="Asperamanca" date="1379657781"]As far as I understood QObject's destructor code, the parent will know that the object has already been deleted, and will not delete it a second time.[/quote]If the child was removed from the stack first, the parent will know and won't try to destroy it again.

    But, if the parent destroys the child first, the stack won't know and will attempt to destroy it again. See http://qt-project.org/doc/qt-5.1/qtcore/objecttrees.html for an example scenario.

    Here's another:
    @
    // BAD CODE!!!
    class BigObject : public QObject {
    QTimer timer;

    public:
    BigObject(QObject *parent = 0)
    : QObject(parent)
    , timer(this)
    {}
    }
    @
    The QTimer is created first and the BigObject is created second. So, the stack will try to destroy them in the reverse order: BigObject first, QTimer second.

    The BigObject will destroy the QTimer, and then the stack will try to do it a second time.



  • [quote author="JKSH" date="1379662799"]If the child was removed from the stack first, the parent will know and won't try to destroy it again.

    But, if the parent destroys the child first, the stack won't know and will attempt to destroy it again.[/quote]

    True. Now thinking about it, my use case is different. I call delete explicitly, not implicitly via stack.



  • Getting back to this thread for another related question.

    When using object pointers, at application exit (via the window close button or explicit code call) should I take care of deleting the remaining pointers or some cleaning steps, or Qt will take care of this? for example, in the next code:
    @int main(int argc, char *argv[]){
    QApplication app(argc, argv);

    QWidget * my_app_win = new QWidget();
    my_app_win->show();

    return app.exec();
    }@
    when I close the my_app_win window via the window close button, will it be terminated correctly and the my_app_win pointer deleted or should I take care of it?



  • Hi, in this case, a delete is needed, or you should set Qt::WA_QuitOnClose attribute for the widget or using smart pointer.

    BTW, for the widget which doesn't have a parent, you had better allocate it on the stack.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.