This is an interesting question, let's demystify it:
From the official documentation:
The connection will be automatically disconnected if the sender is destroyed. However, you must ensure that all objects used in the functor are still alive when they emit a signal.
In your example, you are copying the generic pointer created when used inside the lambda, otherwise the copy will not be made for the generic pointer. A copy will naturally increase the reference count for an object inside shared pointers. Here is the relevant documentation from shared_ptr :
Property of an object can only be transferred to another shared_ptr by copying or copying, assigning its value to another shared_ptr
Now we separate these two cases:
If you do not copy the common pointer, there is only one reference to the object, and therefore, when clearing is performed for your document repository, there are no more links on it, and therefore, the object can be destroyed, considering that you are not doing anything useful inside the lambda -functions and therefore can be optimized.
When you copy a shared pointer, there is one reference to an object outside of lambad, and inside there will also be one due to a shared copy of the pointer. Now that the semantics of the Qt connection are made, make sure that the object is supported according to the documentation above.
Therefore, when your Gui object is destroyed, it will also make the whole trip, and during this period, it can make sure that there is no longer a reference to the object and, therefore, the destructor called after your print operator gui destructor.
You can probably improve the test code by adding another print statement to it:
qDebug("+Gui"); for(int i=0; i<3; i++) CreateDoc(); qDebug("+/-Gui"); mRepo.mDocs.clear(); qDebug("-Gui");
This will also explicitly indicate that you are deleting document objects after deleting the repository, and not when the method ends when they are created. The result will be more clear:
main.pro
TEMPLATE = app TARGET = main QT += widgets CONFIG += c++11 SOURCES += main.cpp
main.cpp
#include <QApplication> #include <memory> #include <QUndoCommand> #include <QWidget> #include <QDebug> struct Document { Document() { qDebug("Document"); } ~Document() { qDebug("~Document"); } QUndoStack mUndostack; }; struct DocumentRepository { DocumentRepository() { qDebug("DocumentRepository"); } ~DocumentRepository() { qDebug("~DocumentRepository"); } void AddDoc(std::shared_ptr<Document> doc) { mDocs.emplace_back(doc); } std::vector<std::shared_ptr<Document>> mDocs; }; struct Gui : public QWidget { Gui(DocumentRepository& repo) : mRepo(repo) { qDebug("+Gui"); for(int i=0; i<3; i++) CreateDoc(); qDebug("+/-Gui"); mRepo.mDocs.clear(); qDebug("-Gui"); } ~Gui() { qDebug("~Gui"); } void CreateDoc() { auto docPtr = std::make_shared<Document>(); connect(&docPtr->mUndostack, &QUndoStack::cleanChanged, this, [=](bool) { /* qDebug() << docPtr->mUndostack.count(); */ }, Qt::QueuedConnection); mRepo.AddDoc(docPtr); } DocumentRepository& mRepo; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); DocumentRepository repo; Gui g(repo); g.show(); return 0; }
Exit
DocumentRepository +Gui Document Document Document +/-Gui ~Document ~Document ~Document -Gui ~Gui ~DocumentRepository