Using Singleton Class contains QComboxBox , crashed
-
show the widget and select the item, program will crash on exit
class SettingWidget : public QWidget { Q_OBJECT public: ~SettingWidget(){} static SettingWidget& instance(){ static SettingWidget mInstance; return mInstance; } private: explicit SettingWidget(QWidget *parent = 0) : QWidget(parent) { cbox = new QComboBox(this); cbox->addItem("1"); } QComboBox * cbox; }; main.cpp QApplication a(argc, argv); SettingWidget::instance().show(); return a.exec();
console:
QBasicTimer::start: QBasicTimer can only be used with threads started with QThread
15:18:50: C:/Users/black/Documents/build-untitled29-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/untitled29.exe crashed.sorry ,i do not how to post stack. I do not use thread
-
-
@trreeee said in Using singleton contain QComboxBox , crashed:
static SettingWidget& instance();
You may know C++ rules for this better than I, but although this is a
static
method returning a reference to aSettingWidget
object you have not actually created any such static object for it to return. The code does not show the definition ofinstance()
. -
@JonB said in Using singleton contain QComboxBox , crashed:
you have not actually created any such static object for it to return
It could be a static variable inside instance() - that's why I asked for its implementation :-)
-
@trreeee
You keep altering your code, so I don't know how accurate to what you really have it is or when the updates are going to end....One thing: it may not be relevant, but I don't think you should go
cbox->show();
during the constructor forSettingWidget
, that is not a place to putshow()
s. -
@trreeee
Did you at least test your code withSettingWidget sw;
instead ofSettingWidget::instance()
to verify that it really is thestatic
which is the issue?console: QBasicTimer::start: QBasicTimer can only be used with threads started with QThread 15:18:50: C:/Users/black/Documents/build-untitled29-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/untitled29.exe crashed.
Now that you post this it looks like you are using threds and you issue lies there, nothing to do with
static
.... Is the code you are posting your whole program, or part of something else? -
I tried out your sample code, and for me, it runs fine :) However, it does crash on exit, because
SettingWidget::cbox
is destroyed twice. Once, because its a child of the singleSettingWidget
instance (this is done by Qt), and then because its astatic
variable (this done by C++ specifications).The fix is to unset the parent-child relationship in the
SettingWidget
destructor, like:~SettingWidget() { if ((cbox) && (cbox->parent() == this)) { cbox->setParent(nullptr); } }
The
if
conditions aren't really necessary here, but good practice anyway :)Cheers.
-
@Paul-Colby said in Using singleton contain QComboxBox , crashed:
if ((cbox) && (cbox->parent() == this)) {
cbox->setParent(nullptr);
}thank you, I crash on exit also. I tried out "if code", the program still crash.
if I do not select the QComboBox 's item, the program can exit normally
-
@trreeee said in Using Singleton Class contains QComboxBox , crashed:
exit(0) to exit program. the program can exit normally, and ~SettingWidget(){} can be called normally,
Are you sure
~SettingWidget()
is called in this case? Sounds more to me like you are just avoiding the (incorrect) destruction behaviour this way? But up to you.My 2 cents? If you must have this singleton widget, I would have
new
ed astatic SettingWidget *mInstance;
rather than having astatic SettingWidget
. Your way the (static
) destruction comes after the parent has been destroyed, not a good idea. -
@JonB said in Using Singleton Class contains QComboxBox , crashed:
@trreeee said in Using Singleton Class contains QComboxBox , crashed:
exit(0) to exit program. the program can exit normally, and ~SettingWidget(){} can be called normally,
Are you sure
~SettingWidget()
is called in this case? Sounds more to me like you are just avoiding the (incorrect) destruction behaviour this way? But up to you.My 2 cents? If you must have this singleton widget, I would have
new
ed astatic SettingWidget *mInstance;
rather than having astatic SettingWidget
. Your way the (static
) destruction comes after the parent has been destroyed, not a good idea.Thank you, I tested it, it did work
I also found this way#include <QCoreApplication> static Widget* instance(){ static Widget* impl = new Widget; connect(qApp, &QCoreApplication::aboutToQuit, impl, &Widget::deleteLater); return impl; }