[SOLVED] QMainWindow as Singleton



  • I have a class MyWindow inheriting from QMainWindow and is a Singleton. My code looks as follows:

    @class MyWindow : public QMainWindow
    {
    public:

          static MyWindow* instance()
          {
               if(mWindow == NULL)  mWindow = new MyWindow();
               return mWindow;
          }
    
     protected:
    
          MyWindow()
               : QMainWindow()
          {
          }
    
     private:
    
          static MyWindow *mWindow;
    

    };

    MyWindow* MyWindow::mWindow = NULL;

    int main(int argc, char *argv[])
    {
    QApplication application(argc, argv);
    MyWindow *window = MyWindow::instance();
    window->show();
    application.exec();

     delete window;
     return 0;
    

    }@

    When I do this, once I clode the window (with the X in the title bar), I get a lot of glibc errors saying that I called free() on an invalid pointer. So when I remove the delete statement from my main function, everything works. Also when I make MyWindow’s constructor public and do this:

    @int main(int argc, char *argv[])
    {
    QApplication application(argc, argv);
    MyWindow *window = new MyWindow();
    window->show();
    application.exec();

     delete window;
     return 0;
    

    }@

    everything also works fine. What am I doing wrong? Did I miss something obvious?



  • Try to add destructor function to your class.



  • I've tried adding a destructor (and also making it virtual), but got the same problem.



  • Maybe you widget gets already deleted?

    http://qt-project.org/doc/qt-4.8/qwidget.html#close

    bq. If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. A close events is delivered to the widget no matter if the widget is visible or not.



  • Actually, i didn't have any problem with your code!! Could not reproduce the error codes.
    Have you tried cleaning the project and rebuilding again ?



  • Yip, I'm currently using Qt5 Alpha. Maybe I should checkout the Beta release.
    But I think AcerExtensa has a good point there.



  • Print some text out of the destructor... I am sure AcerExtensa is right... exec() has ended so lifecycle has finished.. In doc you can find recomendation how to handle cleanup "We recommend that you connect clean-up code to the aboutToQuit() signal, instead of putting it in your application's main() function."

    My personal note is: When you use singleton, there is no specific reason why to call destructor manually(unless you have connection you have to close or something, for mainwindow there is no need).

    And you can implement it like that, so no delete needed.

    @class MyWindow : public QMainWindow
    {
    public:

          static MyWindow* instance()
          {
               static MyWindow window;
               return &window;
          }
    
     protected:
    
          MyWindow()
               : QMainWindow()
          {
          }
    
     private:
    

    };@


  • Moderators

    Delete is not needed anyway... you end the process just after it, so the memory will be freed by the system. Usually Qt programs don't use delete in a visible way, too:
    @
    return app.exec();
    @



  • Jip, since I only delete the window right before my app exits, cleanup is not really needed here. But it's always a good idea to clean up after yourself, even if it's not needed. So just a good old habbit of mine.


  • Moderators

    If you added a destructor to your class, I assume you were calling @delete mWindow;@ there. Did you also set mWindow to NULL? Since it's a static variable, I'm wondering if it's trying to get cleaned up twice somehow.



  • Ok guys, I added a cout line to my destructor, but it is never called (except if I call "delete window" manually). So the window is not destructed, or if it is, the desctructor doesn't get called.



  • And adam.bogocz, I can't use the Meyer Singleton implmentation, since I do some init-stuff that requires dynamic allocation.



  • well, in your example there is simple constructor without any args, so if constructor allocates memory from heap it does not matter if object is static or not...but if real thing looks different then sure..

    generally Qt idea involves One parrent which is on stack(usoally MainWindow) and all other QObjects are his childs ... creating tree(or more) which should always have root element on the stack.. so you NEVER call delete directly for cleanup purposes. just when you want to release object you dont need during runtime anymore..

    I have got into troubles once, when I started with Qt, I was deleting everything by myself and there was a case when I was trying to delete stuff that Qt already did...

    Anyways I think that you can mark this thread as solved ;)


Log in to reply
 

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