Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between QPointer, QSharedPointer and QWeakPointer classes in Qt?

I have read from the Qt documentations about QPointer, QSharedPointer and QWeakPointer classes. It says:

  1. QPointer is a template class that provides guarded pointers to Qt objects and behaves like a normal C++ pointer except that it is automatically set to 0 when the referenced object is destroyed and no "dangling pointers" are produced.

  2. QSharedPointer class holds a strong reference to a shared pointer.

  3. QWeakPointer class holds a weak reference to a shared pointer.

My questions is "What is the difference between these classes?". i.e what is the difference between a pointer to an object and a reference to a pointer? Are they all pointers to objects with different mechanisms and behaviors?

like image 775
Nejat Avatar asked Mar 10 '14 15:03

Nejat


People also ask

What is QPointer in Qt?

The QPointer class is a template class that provides guarded pointers to QObject. A guarded pointer, QPointer<T>, behaves like a normal C++ pointer T *, except that it is automatically set to 0 when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases).

Is QPointer a smart pointer?

The QPointer class is a templated class which provides a smart pointer for QObject.

Is QSharedPointer thread safe?

Thread-SafetyDifferent QSharedPointer and QWeakPointer objects can safely be accessed by multiple threads at the same time.


2 Answers

QPointer:
QPointer can only point to QObject instances. It will be automatically set to nullptr if the pointed to object is destroyed. It is a weak pointer specialized for QObject.

Consider this fragment:

QObject *obj = new QObject;
QPointer<QObject> pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now

QSharedPointer
A reference-counted pointer. The actual object will only be deleted, when all shared pointers are destroyed. Equivalent to std::shared_ptr.

int *pI = new int;
QSharedPointer<int> pI1(pI);
QSharedPointer<int> pI2 = pI1;
pI1.clear();
// pI2 is still pointing to pI, so it is not deleted
pI2.clear();
// No shared pointers anymore, pI is deleted

Note that as long as there is a shared pointer, the object is not deleted!

QWeakPointer:
Can hold a weak reference to a shared pointer. It will not prevent the object from being destroyed, and is simply reset. Equivalent to std::weak_ptr, where lock is equivalent to toStrongRef.

int *pI = new int;
QSharedPointer<int> pI1(pI);
QWeakPointer<int> pI2 = pI1;
pI1.clear();
// No shared pointers anymore, pI is deleted
//
// To use the shared pointer, we must "lock" it for use:
QSharedPointer<int> pI2_locked = pI2.toStrongRef();
Q_ASSERT(pI2_locked.isNull());

This can be used if you need access to an object that is controlled by another module.

To use a weak pointer, you must convert it to a QSharedPointer. You should never base a decision on the weak pointer being valid. You can only use data() or isNull() to determine that the pointer is null.

Generally, to use a weak pointer, you must convert it to a shared pointer since such an operation ensures that the object will survive for as long as you are using it. This is equivalent to "locking" the object for access and is the only correct way of using the object pointed to by a weak pointer.

QScopedPointer:
This is just a helper class that will delete the referenced object when the pointer goes out of scope. Thus, binds a dynamically allocated object to a variable scope.

You can use this for RAII semantics for locals, e.g.:

MyClass *foo() {
    QScopedPointer<MyClass> myItem(new MyClass);
    // Some logic
    if (some condition) {
        return nullptr; // myItem will be deleted here
    }
    return myItem.take(); // Release item from scoped pointer and return it
}

The item will also be deleted in case of an exception

Another use case can be member variables of an object. Then you don't need to write a destructor for those:

class MyClass {
public:
    MyClass() : myPtr(new int) {}
private:
    QScopedPointer<int> myPtr; // Will be deleted automatically when containing object is deleted
}
like image 146
king_nak Avatar answered Nov 06 '22 04:11

king_nak


  • QSharedPointer : std::shared_ptr
  • QWeakPointer : std::weak_ptr
  • QScopedPointer : std::unique_ptr
  • QPointer : no STL equivalent. Nulled when the QObject destructs.
like image 29
Keith Russell Avatar answered Nov 06 '22 06:11

Keith Russell