Trying to create a singleton and getting LNK2019 error
-
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
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 viaqDebug() << 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.
-
I did not understand issue clearly. Let me try to answer.
- when you put the qDebug() << str , are you seeing out put on the qtcreator console window ?
- Are you also appending the string to your textedit as well ?
-
- yes, every time it's called
- yes, but it's only showing up the first time MainWindow::console("whatever") is called, regardless from where it's called.
-
@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:
headerclass 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 } };
-
@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. :)