SoFunction
Updated on 2025-04-12

Qt The specific use of smart pointers

QScopedPointer

QScopedPointerIt is a smart pointer provided by Qt, which is mainly used to simplify resource management and prevent memory leaks and hanging pointer problems. It belongs to Qt's memory management tool, which automatically handles the life cycle of an object, ensuring that the object is destroyed when it is out of scope.QScopedPointerIt is based on the C++11 standardstd::unique_ptrImplemented, but it has the characteristics of Qt and is usually used for the management of local objects.

  • Automatically delete object: whenQScopedPointerWhen out of scope, it will automatically release the held object. This means no manualdeleteObject.
  • Cannot copy:QScopedPointerCopy operation is not supported to prevent accidental multiple pointers pointing to the same object.
  • Transfer of ownership: Can be usedreset()Or through the constructor,QScopedPointerThe ownership of   transfers to anotherQScopedPointer

1. Automatically delete objects

QScopedPointerThe most common usage is to manage dynamically allocated objects within a function or local scope. At the end of the scope,QScopedPointerAutomatically destroy objects without explicit callsdelete

#include <QScopedPointer>
#include <QDebug>

class MyClass {
public:
    MyClass() { qDebug() << "MyClass constructed"; }
    ~MyClass() { qDebug() << "MyClass destructed"; }
};

void testScopedPointer() {
    QScopedPointer<MyClass> ptr(new MyClass);
    // When the function returns, ptr is out of scope and the object will be automatically destroyed} // Here, the MyClass object will be automatically deleted

2. Transfer of ownership

QScopedPointerCopy operation is not supported, but can be passedreset()Or the constructor transfers ownership. so,QScopedPointerResources can be passed between different scopes.

#include <QScopedPointer>
#include <QDebug>

class MyClass {
public:
    MyClass() { qDebug() << "MyClass constructed"; }
    ~MyClass() { qDebug() << "MyClass destructed"; }
};

void transferOwnership() {
    QScopedPointer<MyClass> ptr1(new MyClass);
    // Transfer ownership from ptr1 to ptr2    QScopedPointer<MyClass> ptr2(());
    // Now ptr1 no longer has the MyClass object, ptr2 has it
    // ptr1 no longer points to the object, but the object still exists and is managed by ptr2} // Here, when ptr2 is out of scope, the MyClass object will be automatically deleted

3. Manage private data

In many classes of Qt, private data (usually a class containing implementation details) is encapsulated in oneQScopedPointermiddle. This ensures that private data is automatically released in the class's destructor while maintaining the simplicity and security of the code.

Example:QFilekind

class QFilePrivate : public QIODevicePrivate {
    // Private data member};

class QFile : public QIODevice {
public:
    QFile();
    ~QFile();

private:
    QScopedPointer<QFilePrivate> d_ptr;
};

In this example,QFileClass useQScopedPointerCome to manageQFilePrivateObject. whenQFileWhen object destruction,QScopedPointerIt will be deleted automaticallyQFilePrivateObject, ensure that memory is freed.

QSharedPointer

QSharedPointerIt manages the life cycle of an object through reference counting, multipleQSharedPointerObjects can share the same resource. WheneverQSharedPointerWhen a copy construct or assignment operation occurs, the reference count will increase, and when aQSharedPointerWhen destroyed, the reference count will decrease. When the reference count drops to 0, the pointing object will be automatically deleted.

#include <QSharedPointer>
#include <QDebug>

class MyClass {
public:
    void print() { qDebug() << "Hello from MyClass!"; }
};

int main() {
    // Create a QSharedPointer object and manage the life cycle of MyClass object    QSharedPointer<MyClass> ptr1(new MyClass);

    // Create another QSharedPointer and share the object managed by ptr1    QSharedPointer<MyClass> ptr2 = ptr1;

    // Use both ptr1 and ptr2 to access the same object    ptr1->print();
    ptr2->print();

    // There is no need to manually release memory. When the last QSharedPointer is destroyed, the MyClass object will be deleted automatically.    return 0;
}

Key Features

  • Reference count:QSharedPointerManage the life cycle of an object through reference counting. Whenever there is a new oneQSharedPointerWhen an object points to the same resource, the reference count increases; when aQSharedPointerWhen an object is destroyed, the reference count will decrease.
  • Automatic destruction: When the last reference count is 1QSharedPointerWhen destroyed, the pointing object will be automatically deleted, thus avoiding memory leakage.
  • Thread Safety:QSharedPointerThe reference counting operation is thread-safe, but it does not itself guarantee that the object pointed to is thread-safe. If multiple threads access the sameQSharedPointerObject, it must be ensured that other threads access the object synchronously.

Things to note

  • QSharedPointerThe reference counting mechanism can cause circular reference problems in some cases, especially when two or more objects hold each other'sQSharedPointerhour. At this point, even if these objects are no longer in use, the reference count will not drop to zero, because they refer to each other, causing the objects to be destroyed, resulting in memory leaks.

    Solution: UseQWeakPointerTo break the circular reference.QWeakPointeris a weak reference, holding oneQSharedPointerObject, but it does not increase the reference count. whenQSharedPointerWhen destroyed,QWeakPointerAutomatically change to a null pointer.

  • Don't mix naked pointers andQSharedPointer``QSharedPointerNeed to make sure it is the only memory manager. If you use bare pointers andQSharedPointerManaging the same memory may result in double releases or memory leaks. Therefore, avoid sharing the same resource with the smart pointer, ensuring that the object is always managed by the smart pointer.

QWeakPointer

QWeakPointeryesQSharedPointerA supplement to  it does not own the object itself.QWeakPointerOnly inQSharedPointerA reference count is non-zero to provide the ability to access the object, but does not prevent the object from being destroyed. in other words,QWeakPointerAllows you to refer to an object without making it impossible to destroy.

QWeakPointerMain features:

  • Weak quote:QWeakPointerDo not increase the reference count of the object, which means it will not prevent the object from being destroyed.
  • Prevent circular references:QWeakPointerSolvedQSharedPointerPossible circular reference problems.
  • Secure access methods:QWeakPointerCan be passedtoStrongRef()Method conversion toQSharedPointer, thereby safely accessing the target object.

QWeakPointerandQSharedPointerCooperation

QWeakPointerUsually withQSharedPointerUse together to avoid circular references. In some cases, two objects will refer to each other, causing their reference count to always be zero, resulting in memory leaks.QWeakPointerThis circular reference chain can be broken, which allows object A to hold object BQWeakPointer, while object B can hold object A'sQSharedPointer, thus ensuring that the life cycle of objects A and B is fromQSharedPointermanage.

QWeakPointerCommon usage of

Here is a useQWeakPointerSpecific examples:

class B;  // Forward declaration

class A {
public:
    QSharedPointer<B> b;  // B's shared pointer};

class B {
public:
    QWeakPointer<A> a;  // A's weak reference};

int main() {
    QSharedPointer<A> a(new A);  // Create A object    QSharedPointer<B> b(new B);  // Create B object
    a->b = b;  // A holds B's shared pointer    b->a = a;  // B holds a weak reference to A
    return 0;  // When the program exits, A and B will be automatically destroyed to avoid memory leakage}

Things to note

When using QWeakPointer, be sure to useisNULLDetermine whether resources are released

QSharedPointer<MyClass> shared(new MyClass(20));
QWeakPointer<MyClass> weak(shared);

qDebug() << "Shared pointer value:" << shared->getValue();
qDebug() << "Weak pointer value:" << ()->getValue();

(); // Delete the shared object pointed to// At this time, the reference count of the MyClass object is 0 and will be automatically deleted, and the QWeakPointer object weak is also null.
if (()) {  // Determine whether weak is null	qDebug() << "Weak pointer is null - object has been deleted"; // implement}
else {
	qDebug() << "Weak pointer is not null - object still exists";
}

QPointer

QPointeris a Qt object (e.g.QObject) template class, which automatically manages the life cycle of the object. When aQObjectWhen destroyed,QPointerIts pointer will be set tonullptr, This allows the program to detect that the pointing object has been deleted, thereby avoiding access to deleted objects and avoiding dangling pointer issues.QPointerOnly used for managementQObjector an object of its subclass. If you need to manage other types of objects, you can consider using other smart pointers, such asstd::shared_ptrorstd::unique_ptr

#include <QPointer>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QWidget window;
    QVBoxLayout *layout = new QVBoxLayout(&window);

    QPushButton *button = new QPushButton("Click me");
    QPointer<QPushButton> pButton(button);

    layout->addWidget(button);
    ();

    QObject::connect(button, &QPushButton::clicked, [&] {
        if (pButton) {
            qDebug() << "Button exists, text:" << pButton->text();
        } else {
            qDebug() << "Button has been deleted";
        }
    });

    // Delete the simulated button    QObject::connect(button, &QPushButton::clicked, [&] {
        delete button;
    });

    return ();
}

This is the end of this article about the specific use of Qt smart pointers. For more related Qt smart pointers, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!