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. Trying to create a singleton and getting LNK2019 error
Forum Updated to NodeBB v4.3 + New Features

Trying to create a singleton and getting LNK2019 error

Scheduled Pinned Locked Moved Solved General and Desktop
singletonc++
18 Posts 4 Posters 7.8k Views 1 Watching
  • 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.
  • D Offline
    D Offline
    dheerendra
    Qt Champions 2022
    wrote on 10 Feb 2017, 02:04 last edited by
    #9

    add this line to the beginning of you MainWindow.cpp file. Just see the code snippet.

    #include "MainWindow.h"

    MainWindow* MainWindow::w_instance = NULL;

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {
    }

    Dheerendra
    @Community Service
    Certified Qt Specialist
    http://www.pthinks.com

    E 1 Reply Last reply 10 Feb 2017, 04:43
    5
    • D dheerendra
      10 Feb 2017, 02:04

      add this line to the beginning of you MainWindow.cpp file. Just see the code snippet.

      #include "MainWindow.h"

      MainWindow* MainWindow::w_instance = NULL;

      MainWindow::MainWindow(QWidget *parent)
      : QMainWindow(parent)
      {
      }

      E Offline
      E Offline
      eggbertx
      wrote on 10 Feb 2017, 04:43 last edited by
      #10

      @dheerendra
      Alright, that seems to be working but now I've run into a another problem. I can send the MainWindow::console string argument to the Qt Creator console via

      qDebug() << str;
      

      but regardless of how many times I call the function, it's only appending said argument to the console widget (QTextEdit) via

      ui->consoleWidget->appendPlainText(str.toString());
      

      the first time MainWindow::console("whatever") is called.

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dheerendra
        Qt Champions 2022
        wrote on 10 Feb 2017, 04:55 last edited by dheerendra 2 Oct 2017, 05:32
        #11

        I did not understand issue clearly. Let me try to answer.

        1. when you put the qDebug() << str , are you seeing out put on the qtcreator console window ?
        2. Are you also appending the string to your textedit as well ?

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        E 1 Reply Last reply 10 Feb 2017, 20:06
        8
        • D dheerendra
          10 Feb 2017, 04:55

          I did not understand issue clearly. Let me try to answer.

          1. when you put the qDebug() << str , are you seeing out put on the qtcreator console window ?
          2. Are you also appending the string to your textedit as well ?
          E Offline
          E Offline
          eggbertx
          wrote on 10 Feb 2017, 20:06 last edited by
          #12

          @dheerendra

          1. yes, every time it's called
          2. yes, but it's only showing up the first time MainWindow::console("whatever") is called, regardless from where it's called.
          1 Reply Last reply
          0
          • E Offline
            E Offline
            eggbertx
            wrote on 13 Feb 2017, 16:17 last edited by eggbertx
            #13

            Is bumping a thread for sake of trying to resolve the issue against the rules?

            K 1 Reply Last reply 13 Feb 2017, 16:45
            0
            • E eggbertx
              13 Feb 2017, 16:17

              Is bumping a thread for sake of trying to resolve the issue against the rules?

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 13 Feb 2017, 16:45 last edited by kshegunov
              #14

              @eggbertx said in Trying to create a singleton and getting LNK2019 error:

              Is bumping a thread for sake of trying to resolve the issue against the rules?

              No it's not, it's the preferred way.

              As for the issue. I wouldn't approach the issue that way. Singletons are pretty bad, and one should do well to avoid them if possible. Whenever one can't avoid using a singleton I always prefer the "pseudo-singleton" approach Qt employs, something along those lines:
              header

              class Singleton : public QObject
              {
              public:
                  Singleton(QObject * parent = Q_NULLPTR);
              
                  static Singleton * instance();
                  
              private:
                  static Singleton * _instance;
              };
              

              source

              Singleton * Singleton::_instance = Q_NULLPTR;
              
              Singleton::Singleton(QObject * parent)
                  : QObject(parent)
              {
                  Q_ASSERT(!_instance);
                  _instance = this;
              }
              
              Singleton * Singleton::instance()
              {
                  return _instance;
              }
              

              Then you create as a stack object in main() and use everywhere:

              int main(int argc, char ** argv)
              {
                  QApplication app(argc, argv);
              
                  Singleton singleton(&app);
                  // Rest of code
              }
              

              This particular implementation does not suffer the usual problems with lazy-initialization singletons as memory leaking and thread-unsafe creation, but still does couple up the components. Anyway, a so-constructed global object one can use to connect with signals and slots to whatever UI control is needed at any point and does not impose a strange and unnecessary way of creating the main window. For example consider this:

              void Singleton::console(const QString & line) // Make a slot in the header
              {
                  QTextStream stream(&allText); // allText is a member variable of type QString
                  stream << line << endl;
              
                  emit textChanged(allText);  // void textChanged(const QString &) is a notification signal
              }
              

              Then one could directly hook up this class' instance to the UI component:

              class MainWindow : public QMainWindow
              {
              	Q_OBJECT
              
              public:
                  MainWindow()
                      : QMainWindow(Q_NULLPTR)
                  {
                      ui.setupUi(this); // Or w/e is needed to set up the UI
              
                      QObject::connect(Singleton::instance(), &Singleton::textChanged, ui.textEditWidget, &QTextEdit::setPlainText); // All that's really needed
                  }
              };
              

              Read and abide by the Qt Code of Conduct

              E 1 Reply Last reply 13 Feb 2017, 17:54
              0
              • K kshegunov
                13 Feb 2017, 16:45

                @eggbertx said in Trying to create a singleton and getting LNK2019 error:

                Is bumping a thread for sake of trying to resolve the issue against the rules?

                No it's not, it's the preferred way.

                As for the issue. I wouldn't approach the issue that way. Singletons are pretty bad, and one should do well to avoid them if possible. Whenever one can't avoid using a singleton I always prefer the "pseudo-singleton" approach Qt employs, something along those lines:
                header

                class Singleton : public QObject
                {
                public:
                    Singleton(QObject * parent = Q_NULLPTR);
                
                    static Singleton * instance();
                    
                private:
                    static Singleton * _instance;
                };
                

                source

                Singleton * Singleton::_instance = Q_NULLPTR;
                
                Singleton::Singleton(QObject * parent)
                    : QObject(parent)
                {
                    Q_ASSERT(!_instance);
                    _instance = this;
                }
                
                Singleton * Singleton::instance()
                {
                    return _instance;
                }
                

                Then you create as a stack object in main() and use everywhere:

                int main(int argc, char ** argv)
                {
                    QApplication app(argc, argv);
                
                    Singleton singleton(&app);
                    // Rest of code
                }
                

                This particular implementation does not suffer the usual problems with lazy-initialization singletons as memory leaking and thread-unsafe creation, but still does couple up the components. Anyway, a so-constructed global object one can use to connect with signals and slots to whatever UI control is needed at any point and does not impose a strange and unnecessary way of creating the main window. For example consider this:

                void Singleton::console(const QString & line) // Make a slot in the header
                {
                    QTextStream stream(&allText); // allText is a member variable of type QString
                    stream << line << endl;
                
                    emit textChanged(allText);  // void textChanged(const QString &) is a notification signal
                }
                

                Then one could directly hook up this class' instance to the UI component:

                class MainWindow : public QMainWindow
                {
                	Q_OBJECT
                
                public:
                    MainWindow()
                        : QMainWindow(Q_NULLPTR)
                    {
                        ui.setupUi(this); // Or w/e is needed to set up the UI
                
                        QObject::connect(Singleton::instance(), &Singleton::textChanged, ui.textEditWidget, &QTextEdit::setPlainText); // All that's really needed
                    }
                };
                
                E Offline
                E Offline
                eggbertx
                wrote on 13 Feb 2017, 17:54 last edited by
                #15

                @kshegunov The first example works perfectly. And thus far, I've only been using signals and slots for actions and button presses.

                K 1 Reply Last reply 13 Feb 2017, 19:01
                0
                • E eggbertx
                  13 Feb 2017, 17:54

                  @kshegunov The first example works perfectly. And thus far, I've only been using signals and slots for actions and button presses.

                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 13 Feb 2017, 19:01 last edited by
                  #16

                  I don't follow. What first example you mean?

                  Read and abide by the Qt Code of Conduct

                  E 1 Reply Last reply 13 Feb 2017, 20:29
                  0
                  • K kshegunov
                    13 Feb 2017, 19:01

                    I don't follow. What first example you mean?

                    E Offline
                    E Offline
                    eggbertx
                    wrote on 13 Feb 2017, 20:29 last edited by
                    #17

                    @kshegunov Sorry, I meant the second code block, not the first. I'm not very familiar with assertions in general, so I've never heard of Q_ASSERT. Adding the code in the second block fixed the issue.

                    K 1 Reply Last reply 13 Feb 2017, 22:04
                    0
                    • E eggbertx
                      13 Feb 2017, 20:29

                      @kshegunov Sorry, I meant the second code block, not the first. I'm not very familiar with assertions in general, so I've never heard of Q_ASSERT. Adding the code in the second block fixed the issue.

                      K Offline
                      K Offline
                      kshegunov
                      Moderators
                      wrote on 13 Feb 2017, 22:04 last edited by
                      #18

                      @eggbertx said in Trying to create a singleton and getting LNK2019 error:

                      Sorry, I meant the second code block, not the first. I'm not very familiar with assertions in general, so I've never heard of Q_ASSERT.

                      The assertion here is only a tool to detect creating more than one instance of the class. Q_ASSERT is a Qt macro for regular debug assertions, it will be removed in release mode, so its purpose (as assertions in general) is to catch programmer errors while debugging. So if you use the class above like this:

                      Singleton object1;
                      Singleton object2; //< Here the assertion will be tripped and you can catch the error while debugging
                      

                      Adding the code in the second block fixed the issue.

                      Do you mean the main window constructor where the connect is made? All code blocks are part of one single example, so I'd expect them to work together only. :)

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      1

                      18/18

                      13 Feb 2017, 22:04

                      • Login

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