QScopedPointer
QScopedPointer
It 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.QScopedPointer
It is based on the C++11 standardstd::unique_ptr
Implemented, but it has the characteristics of Qt and is usually used for the management of local objects.
- Automatically delete object: when
QScopedPointer
When out of scope, it will automatically release the held object. This means no manualdelete
Object. - Cannot copy:
QScopedPointer
Copy operation is not supported to prevent accidental multiple pointers pointing to the same object. - Transfer of ownership: Can be used
reset()
Or through the constructor,QScopedPointer
The ownership of transfers to anotherQScopedPointer
。
1. Automatically delete objects
QScopedPointer
The most common usage is to manage dynamically allocated objects within a function or local scope. At the end of the scope,QScopedPointer
Automatically 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
QScopedPointer
Copy operation is not supported, but can be passedreset()
Or the constructor transfers ownership. so,QScopedPointer
Resources 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 oneQScopedPointer
middle. This ensures that private data is automatically released in the class's destructor while maintaining the simplicity and security of the code.
Example:QFile
kind
class QFilePrivate : public QIODevicePrivate { // Private data member}; class QFile : public QIODevice { public: QFile(); ~QFile(); private: QScopedPointer<QFilePrivate> d_ptr; };
In this example,QFile
Class useQScopedPointer
Come to manageQFilePrivate
Object. whenQFile
When object destruction,QScopedPointer
It will be deleted automaticallyQFilePrivate
Object, ensure that memory is freed.
QSharedPointer
QSharedPointer
It manages the life cycle of an object through reference counting, multipleQSharedPointer
Objects can share the same resource. WheneverQSharedPointer
When a copy construct or assignment operation occurs, the reference count will increase, and when aQSharedPointer
When 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:
QSharedPointer
Manage the life cycle of an object through reference counting. Whenever there is a new oneQSharedPointer
When an object points to the same resource, the reference count increases; when aQSharedPointer
When an object is destroyed, the reference count will decrease. - Automatic destruction: When the last reference count is 1
QSharedPointer
When destroyed, the pointing object will be automatically deleted, thus avoiding memory leakage. - Thread Safety:
QSharedPointer
The 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 sameQSharedPointer
Object, it must be ensured that other threads access the object synchronously.
Things to note
-
QSharedPointer
The reference counting mechanism can cause circular reference problems in some cases, especially when two or more objects hold each other'sQSharedPointer
hour. 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: Use
QWeakPointer
To break the circular reference.QWeakPointer
is a weak reference, holding oneQSharedPointer
Object, but it does not increase the reference count. whenQSharedPointer
When destroyed,QWeakPointer
Automatically change to a null pointer. - Don't mix naked pointers and
QSharedPointer``QSharedPointer
Need to make sure it is the only memory manager. If you use bare pointers andQSharedPointer
Managing 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
QWeakPointer
yesQSharedPointer
A supplement to it does not own the object itself.QWeakPointer
Only inQSharedPointer
A 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,QWeakPointer
Allows you to refer to an object without making it impossible to destroy.
QWeakPointer
Main features:
- Weak quote:
QWeakPointer
Do not increase the reference count of the object, which means it will not prevent the object from being destroyed. - Prevent circular references:
QWeakPointer
SolvedQSharedPointer
Possible circular reference problems. - Secure access methods:
QWeakPointer
Can be passedtoStrongRef()
Method conversion toQSharedPointer
, thereby safely accessing the target object.
QWeakPointer
andQSharedPointer
Cooperation
QWeakPointer
Usually withQSharedPointer
Use 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.QWeakPointer
This 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 fromQSharedPointer
manage.
QWeakPointer
Common usage of
Here is a useQWeakPointer
Specific 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 useisNULL
Determine 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
QPointer
is a Qt object (e.g.QObject
) template class, which automatically manages the life cycle of the object. When aQObject
When destroyed,QPointer
Its 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.QPointer
Only used for managementQObject
or an object of its subclass. If you need to manage other types of objects, you can consider using other smart pointers, such asstd::shared_ptr
orstd::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!