Results 1 to 20 of 26

Thread: Basic question on new and delete

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    3
    Thanked 7 Times in 6 Posts

    Default Re: Basic question on new and delete

    Quote Originally Posted by Chicken Blood Machine
    ...snip...
    Where QObject really helps out is when you create a GUI. A toplevel window, say derived from QMainWindow, may contain a myriad of other subwidgets within itself (Consider a complex gui that you have created in Designer). When you intsantiate your main window widget, you may do it like this:

    Qt Code:
    1. MyMainWindow* mw = new MyMainWindow(0);// note null parent
    To copy to clipboard, switch view to plain text mode 

    Within the MyMainWindow constructor, there will be code that creates and arranges many child widgets of the main window.


    When you delete the mainwindow, you would do so like this
    Qt Code:
    1. delete mw;
    To copy to clipboard, switch view to plain text mode 

    You don't worry about deleting all the pushbuttons, listboxes, labels etc that are within your main window. Why? because QObject takes care of it with its parent-child model.
    Well, here is the main function, from my main.cpp, from my Homestead application:
    Qt Code:
    1. int main( int argc, char * argv[] ) {
    2. QString strRejected = "";
    3. QApplication app(argc, argv);
    4. app.setQuitOnLastWindowClosed(false);
    5. dlgLogin dlg;
    6. if( dlg.exec() == QDialog::Accepted ){
    7. QSqlDatabase hapdb = QSqlDatabase::addDatabase(DBDRIVER);
    8. hapdb.setHostName(DBHOST);
    9. hapdb.setDatabaseName(DBNAME);
    10. hapdb.setUserName(dlg.dui.leUserName->text());
    11. hapdb.setPassword(dlg.dui.leUserPassword->text());
    12. if ( hapdb.open() ) {
    13. homestead ht;
    14. ht.RevID = dlg.dui.leUserName->text();
    15. ht.show();
    16. app.setQuitOnLastWindowClosed(true);
    17. return app.exec();
    18. } else {
    19. strRejected = QString("The Login was rejected because: %1").arg(hapdb.lastError().text()).toLatin1();
    20. QMessageBox::information(0,"Login Rejected!",strRejected,
    21. QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
    22. return 1;
    23. }
    24. } else {
    25. strRejected = QString("User Canceled the login!").toLatin1();
    26. QMessageBox::information(0,"Login Rejected!",strRejected,
    27. QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
    28. return 2;
    29. }
    30. }
    To copy to clipboard, switch view to plain text mode 
    As I understand your comments, since "dlg" is called only once, and that call is in this function, its memory will be recovered when main goes out of scope (i.e., the app closes). And, hapdb is also instantiated only once so its memory, too, will be reclaimed when the app closes. The ht object, where Homestead really operates, is also instantiated only once and like the others, the memory it uses is returned to the OS when the app closes. So, I don't need as the last three lines of main():
    Qt Code:
    1. delete ht;
    2. delete hapdb;
    3. delete dlg;
    To copy to clipboard, switch view to plain text mode 
    because none of these objects leak memory, even though dlg has a parent:
    Qt Code:
    1. class dlgLogin : public QDialog
    2. {
    3. Q_OBJECT
    4. public:
    5. Ui::dlgLoginUi dui;
    6. dlgLogin()
    7. {
    8. dui.setupUi(this);
    9. dui.leUserName->setText("your revid");
    10. dui.leUserPassword->setText("");
    11. dui.leUserName->setFocus();
    12. dui.leUserName->selectAll();
    13. }
    14. };
    To copy to clipboard, switch view to plain text mode 
    but homestead does not...
    Qt Code:
    1. class homestead : public QMainWindow
    2. {
    3. Q_OBJECT
    4. public:
    5. homestead(QWidget *parent = 0);
    6. ...
    To copy to clipboard, switch view to plain text mode 

    Right?

  2. #2
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanked 42 Times in 37 Posts

    Default Re: Basic question on new and delete

    Quote Originally Posted by GreyGeek
    Well, here is the main function, from my main.cpp, from my Homestead application:
    Qt Code:
    1. int main( int argc, char * argv[] ) {
    2. QString strRejected = "";
    3. QApplication app(argc, argv);
    4. app.setQuitOnLastWindowClosed(false);
    5. dlgLogin dlg;
    6. if( dlg.exec() == QDialog::Accepted ){
    7. QSqlDatabase hapdb = QSqlDatabase::addDatabase(DBDRIVER);
    8. hapdb.setHostName(DBHOST);
    9. hapdb.setDatabaseName(DBNAME);
    10. hapdb.setUserName(dlg.dui.leUserName->text());
    11. hapdb.setPassword(dlg.dui.leUserPassword->text());
    12. if ( hapdb.open() ) {
    13. homestead ht;
    14. ht.RevID = dlg.dui.leUserName->text();
    15. ht.show();
    16. app.setQuitOnLastWindowClosed(true);
    17. return app.exec();
    18. } else {
    19. strRejected = QString("The Login was rejected because: %1").arg(hapdb.lastError().text()).toLatin1();
    20. QMessageBox::information(0,"Login Rejected!",strRejected,
    21. QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
    22. return 1;
    23. }
    24. } else {
    25. strRejected = QString("User Canceled the login!").toLatin1();
    26. QMessageBox::information(0,"Login Rejected!",strRejected,
    27. QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
    28. return 2;
    29. }
    30. }
    To copy to clipboard, switch view to plain text mode 
    As I understand your comments, since "dlg" is called only once, and that call is in this function, its memory will be recovered when main goes out of scope (i.e., the app closes). And, hapdb is also instantiated only once so its memory, too, will be reclaimed when the app closes. The ht object, where Homestead really operates, is also instantiated only once and like the others, the memory it uses is returned to the OS when the app closes. So, I don't need as the last three lines of main():
    Qt Code:
    1. delete ht;
    2. delete hapdb;
    3. delete dlg;
    To copy to clipboard, switch view to plain text mode 
    That would not even compile. None of the variables you mentioned are pointer variables, so how could you ever call delete on them? Your code (above) as listed will not leak any memory, because all objects are created on the stack.

    because none of these objects leak memory, even though dlg has a parent:
    Qt Code:
    1. class dlgLogin : public QDialog
    2. {
    3. Q_OBJECT
    4. public:
    5. Ui::dlgLoginUi dui;
    6. dlgLogin()
    7. {
    8. dui.setupUi(this);
    9. dui.leUserName->setText("your revid");
    10. dui.leUserPassword->setText("");
    11. dui.leUserName->setFocus();
    12. dui.leUserName->selectAll();
    13. }
    14. };
    To copy to clipboard, switch view to plain text mode 
    Dialog does NOT have a parent. Look how you instantiated it

    Qt Code:
    1. dlgLogin dlg; // <- No parent
    To copy to clipboard, switch view to plain text mode 

    It's constructor does not event have a QWidget* 'parent' parameter, so there is no way to create a dlgLogin object with a parent (even if you wanted to).

    What makes you think that it has a parent?

    but homestead does not...
    Qt Code:
    1. class homestead : public QMainWindow
    2. {
    3. Q_OBJECT
    4. public:
    5. homestead(QWidget *parent = 0);
    6. ...
    To copy to clipboard, switch view to plain text mode 

    Right?
    Correct (but not for the reason that you have stated). Your homestead object does not have a parent, because you declared it like this:
    Qt Code:
    1. homestead ht;
    To copy to clipboard, switch view to plain text mode 

    If you wanted it to have a parent, you would have declared it like this:
    Qt Code:
    1. ...
    2. homestead ht(parent); // Parent is some QWidget*, declared further up
    To copy to clipboard, switch view to plain text mode 

    In both cases, the fact theat you declared your widgets with no parent is fine, because you are ensuring their destruction by declaring them on the stack (not as pointers allocated with 'new') and therefore, they are destroyed when they run out of scope.

  3. #3
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    3
    Thanked 7 Times in 6 Posts

    Default Re: Basic question on new and delete

    Quote Originally Posted by Chicken Blood Machine
    That would not even compile. None of the variables you mentioned are pointer variables, so how could you ever call delete on them? Your code (above) as listed will not leak any memory, because all objects are created on the stack.
    That I knew, I was just supposing that if they were created by "new" would it matter if they were deleted using the delete operator because they were going out of scope anyway if, as you say, the OS will always get the memory back.


    Dialog does NOT have a parent. Look how you instantiated it

    Qt Code:
    1. dlgLogin dlg; // <- No parent
    To copy to clipboard, switch view to plain text mode 

    It's constructor does not event have a QWidget* 'parent' parameter, so there is no way to create a dlgLogin object with a parent (even if you wanted to).

    What makes you think that it has a parent?
    Because it inherited from QDialog?
    class dlgLogin : public QDialog

    An ancestor isn't a parent?
    (I told you I was new to C++)

    Correct (but not for the reason that you have stated). Your homestead object does not have a parent, because you declared it like this:
    Qt Code:
    1. homestead ht;
    To copy to clipboard, switch view to plain text mode 

    If you wanted it to have a parent, you would have declared it like this:
    Qt Code:
    1. ...
    2. homestead ht(parent); // Parent is some QWidget*, declared further up
    To copy to clipboard, switch view to plain text mode 

    In both cases, the fact theat you declared your widgets with no parent is fine, because you are ensuring their destruction by declaring them on the stack (not as pointers allocated with 'new') and therefore, they are destroyed when they run out of scope.
    So, using "new" as shown below means that "ui.gridMultiProp" is a parent to *model ??
    Qt Code:
    1. QSqlQueryModel *model = new QSqlQueryModel(ui.gridMultiProp);
    To copy to clipboard, switch view to plain text mode 
    Pardon the dumb questions but you'll dealing with someone who has read perhaps too much and it's all jumbled up inside?
    It's amazing that I can, using QT, write the app I did and that it works.

  4. #4
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanked 42 Times in 37 Posts

    Default Re: Basic question on new and delete

    Quote Originally Posted by GreyGeek
    That I knew, I was just supposing that if they were created by "new" would it matter if they were deleted using the delete operator because they were going out of scope anyway if, as you say, the OS will always get the memory back.
    Ok, then no, it wouldn't matter. As a matter of good practice, I would delete them anyway though.

    Because it inherited from QDialog?
    class dlgLogin : public QDialog

    An ancestor isn't a parent?
    (I told you I was new to C++)
    No, QDialog is its baseclass, not its parent. The parent is the object you pass as the QWidget* parameter (which can be NULL). 'Baseclass', 'superclass' or 'inherited class' are names for the same C++ OO constructs. 'Parent' (in this context) is a Qt construct and refers to ownership, not inheritance. Reading the comprehensive documentation of QObject will explain it more.

    So, using "new" as shown below means that "ui.gridMultiProp" is a parent to *model ??
    Qt Code:
    1. QSqlQueryModel *model = new QSqlQueryModel(ui.gridMultiProp);
    To copy to clipboard, switch view to plain text mode 
    That's correct.

    Pardon the dumb questions but you'll dealing with someone who has read perhaps too much and it's all jumbled up inside?
    It's amazing that I can, using QT, write the app I did and that it works.
    It is amazing. Did you check your prog for memory leaks
    Actually, it's a very bad idea to use Qt to learn C++ (not suggesting that you did it this way). It is much better to learn C++ and get confident with it (warts and all), then start using Qt to see how much easier it makes your life! The QObject parent-child model along with the references counted non-QObjects really help cut down on the amount of memory management that you have to worry about (but you still must be wary).

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
  •  
Qt is a trademark of The Qt Company.