Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Trouble with implementing Singleton
QtWS25 Last Chance

[Solved] Trouble with implementing Singleton

Scheduled Pinned Locked Moved General and Desktop
14 Posts 4 Posters 4.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    StephanWoebbeking
    wrote on last edited by
    #1

    Hi!

    I am trying to get access to the main window within Qt from a callback function, so I thougth first step would be to implement a Singleton to have a pointer to the instance from outside of the object. I read "some easy docu":http://www.qtcentre.org/wiki/index.php?title=Singleton_pattern for the Singleton and have more or less repeated like this:

    mainwindow.h:
    @
    public:
    explicit MainWindow(QWidget parent = 0);
    ~MainWindow();
    static MainWindow
    inst; // My Singleton pointer as far as I understand my code...
    @

    mainwindow.cpp:
    @
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    if ( !inst ) this->inst = this;
    if ( !this->inst ) MainWindow::inst = this;
    ui->setupUi(this);
    ...
    }
    @

    Now, in the first two lines of the MainWindow constructor, I get 4(!) times the error "Fehler: undefined reference to `MainWindow::inst'". So the compiler has understood all 4 references to "inst" in the same way and made 4 times "MainWindow::inst" from it, which looks perfect from my point of view. However, even interpreted correctly, it complains that it doesn't find the reference, which I don't really understand because haven't I defined it correctly in the header file? It doesn't look difficult, but I can't see the problem, so does anyone else see it?

    Thanks for your help,
    Stephan

    1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      Hi, you can also ask Qt's QApplication object for its current main window: QApplication::activeWindow();

      It's a static method so it should be ok to use from your callback function.

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #3

        Singletons should not expose their constructors, destructors and the instance to the public. So in that, your code is wrong.

        Please consult this guide, it has a nice description of the whole topic: "link":http://www.yolinux.com/TUTORIALS/C++Singleton.html.

        (Z(:^

        1 Reply Last reply
        0
        • S Offline
          S Offline
          StephanWoebbeking
          wrote on last edited by
          #4

          @hskoglund
          Ok, that indeed works for the callback function, thanks for the hint. As I am pretty new to Qt I must admit all these little "tools" of the libraries, etc. are not present yet.

          Nevertheless, do you have any idea, why the example given above would not work? It's just for my interest as I probably use your suggestion in the long run, but I would just like to know...

          Stephan

          1 Reply Last reply
          0
          • S Offline
            S Offline
            StephanWoebbeking
            wrote on last edited by
            #5

            @sierdzio

            Thanks for the answer, I am aware of the shortcomings. Initially I had followed these concepts already, but while searching for the problem I tried to make the code more "open" to find the problem behind. Also the guide outlines pretty much exactly the same pattern that I have mentioned, so that's even more of a motivator to wonder what's wrong in the very short outline I have posted. So you see, where the syntactic error is located?

            Stephan

            1 Reply Last reply
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              You are using "this" to point to a static variable (which is available without object). I suspect that might make the compiler unhappy.

              (Z(:^

              1 Reply Last reply
              0
              • hskoglundH Offline
                hskoglundH Offline
                hskoglund
                wrote on last edited by
                #7

                Not unhappy, I'd say instead "confusing", prefixing a static variable with this-> works the same as prefixing it with MainWindow:: or, if inside MainWindow class, not prefixing it at all.

                The problem is that there's no instance of inst declared (it's just defined), that's why the linker returns the error. To get around it, for example declare it directly after the constructor, like this;
                @
                MainWindow* MainWindow::inst = 0;
                @

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  StephanWoebbeking
                  wrote on last edited by
                  #8

                  AFAIK is a static variable always available in the instance context, just only - of course - not the other way around?!? Anyway, that's just one of the four "trials" to access the variable, if only that would be the location of protest from the compiler I would happily change it, but it complains about all 3 others as well. So how would I access that variable???

                  Stephan

                  1 Reply Last reply
                  0
                  • hskoglundH Offline
                    hskoglundH Offline
                    hskoglund
                    wrote on last edited by
                    #9

                    Actually I think it's the linker that complains, because it can't find any location for your static inst variable (and why you need to declare an instance as in my example above).

                    Re. accessing the variable, so either of the 3 ways are fine: prefixing with MainWindow::, prefixing with this-> or not prefixing it at all.
                    (Of course only the first way is valid outside the MainWindow class :-)

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      StephanWoebbeking
                      wrote on last edited by
                      #10

                      If I change the definition according to my first post I only receive errors:

                      @
                      static MainWindow* MainWindow::inst;
                      @
                      -> Fehler: extra qualification 'MainWindow::' on member 'inst' [-fpermissive]
                      static MainWindow* MainWindow::inst;

                      @
                      static MainWindow* inst = 0;
                      @
                      -> Fehler: 'constexpr' needed for in-class initialization of static data member 'MainWindow* MainWindow::inst' of non-integral type [-fpermissive]

                      @
                      static MainWindow* MainWindow::inst = 0;
                      @
                      -> Fehler: extra qualification 'MainWindow::' on member 'inst' [-fpermissive]
                      -> Fehler: 'constexpr' needed for in-class initialization of static data member 'MainWindow* MainWindow::inst' of non-integral type [-fpermissive]

                      @hskoglund you recommend to declare it without "static", is that intentionelly? If you vote for static as well, then isn't it exactly the way I posted it at the beginning?

                      Stephan

                      1 Reply Last reply
                      0
                      • hskoglundH Offline
                        hskoglundH Offline
                        hskoglund
                        wrote on last edited by
                        #11

                        Hi, to make it work you'll have to declare that variable inst 2 times, first inside your MainWindow class (in the .h file):
                        @
                        static MainWindow* inst; // My Singleton pointer as far as I understand my code...
                        @

                        Next, you'll have to write it one more time to create an instance of inst, easiest as I write above, insert it just after the constructor:
                        @
                        ...
                        if ( !inst ) this->inst = this;
                        if ( !this->inst ) MainWindow::inst = this;
                        ui->setupUi(this);
                        }

                        MainWindow* MainWindow::inst = 0; // <--- good place

                        MainWindow::~MainWindow()
                        {
                        delete ui;
                        }
                        @

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          StephanWoebbeking
                          wrote on last edited by
                          #12

                          Wow, that works, thanks a lot for the hint! I must admit I haven't understood in the first place, I forgot why I have to declare it twice even I thought I knew the difference between declaration and definition, but here I missed out. Have to re-read some stuff I guess.

                          Thanks for your patience!
                          Stephan

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            Hi,

                            Out of curiosity, are your callback called from another thread ?

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              StephanWoebbeking
                              wrote on last edited by
                              #14

                              Hoi,

                              yes, indeed, that's why I implemented the Singleton. I receive events from a dll which facilitates an own thread. This one wants to call back on a standard C function which was subject to another thread I opened here and it's also already solved. But from that function obviously I want to feed that information back into the "object-oriented system" anyhow, so at one point I need a static pointer to an instance. That's exactly this point we have discussed here.

                              I was actually missing the "double" definition described by hskoglung above, after I added that everything was fine.

                              Stephan

                              1 Reply Last reply
                              0
                              • mzimmersM mzimmers referenced this topic on

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved