I currently have something like this
QSharedPointer<QMainWindow> cv;
This shared pointer is used as
cV = QSharedPointer<QMainWindow>(new QMainWindow(p));
cV->setAttribute(Qt::WidgetAttribute::WA_DeleteOnClose);
cV->show();
Now if I close the the QMainWindow
then the following code makes the app crash
if(cV)
cV->close(); //This pointer is no longer valid.
My Question is when I closed thecV
QMainWindow
Object (by clicking on the x button of the ) why is the following statement returning true
if(cV)
How could i make it return false
if the Window has been closed?
A shared pointer doesn't magically know when you delete the object it points to. It is an error to manually delete an object whose lifetime is managed by a shared pointer. Since the window self-deletes when it gets closed, you now get dangling shared pointers.
Ergo, you can't use
QSharedPointer
with a widget that isQt::WA_DeleteOnClose
.What you need is a pointer that tracks whether the widget still exists. Such pointer is
QPointer
, it does exactly what you need. That pointer is designed to reset itself to zero when aQObject
gets destroyed.Note that
QPointer
is a weak pointer, it won't delete the window when it goes out of scope.If you need an owning pointer that allows deletion of the underlying
QObject
, there's a way to do it:Since we allow the deletion of the object through other means than the pointer, it is an error to access the object from multiple threads. If the object were to be deleted in another thread, there's a race condition between the null check and the use of dereferenced object. Thus, a
QPointer
, or aScopedObjectPointer
can only be used from object's thread. This is explicitly asserted. TheQ_ASSERT
becomes a no-op in release builds and has no performance impact there.