Smart Pointers


Published on

Smart pointers are similar to regular pointers, but take care of the details of deleting the object being pointed to when it is no longer needed.

Published in: Technology, Education
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Smart Pointers

  1. 1. Qt Smart Pointers By Roman Okolovich
  2. 2. Overview  Memory management in C++ is left up to the programmer.  Smart pointers are the preferred way in C++ to ensure correct management of dynamic memory allocated by new expressions.  Smart pointers are similar to regular pointers, but take care of the details of deleting the object being pointed to when it is no longer needed.  The C++ Standard Library already contains std::auto_ptr, a smart pointer with transfer-of- ownership semantics.  New C++ Standard may be issued by the end of 2010 and it will introduce new smart pointers. 2 7 February 2010
  3. 3. General  Shared pointer versus shared data  When you share pointers, the value of the pointer and its lifetime is protected by the smart pointer class but the object that the pointer is pointing to is completely outside its control.  Sharing of data involves the smart pointer class knowing something about the data being shared (Implicitly Shared Qt Classes).  Strong versus weak pointer  Strong pointers own the object they point to. Multiple strong pointers can share ownership. An object is guaranteed to stay alive as long as at least one strong pointer still points to it.  Weak pointers observe an object. They can be used exactly like strong pointers, but they do not keep their object alive. If an object is destructed, all of its weak pointers will be valued null. 3 7 February 2010
  4. 4. C++0x smart pointers  std::shared_ptr<>  The shared_ptr is a reference-counted pointer that acts as much as possible like a regular C++ data pointer. The shared pointer will automatically destroy its contents only when there are no shared pointers referencing the object originally created for the shared pointer.  std::weak_ptr<>  A weak_ptr is a reference to an object referenced by a shared_ptr that can determine if that object has been deleted or not. weak_ptr itself cannot be dereferenced; accessing the actual pointer requires the creation of a shared_ptr object.  std::unique_ptr<>  unique_ptr will be provided as a replacement for auto_ptr which will be deprecated. It provides all the features of auto_ptr with the exception of unsafe implicit moving from lvalues. Unlike auto_ptr, unique_ptr can be used with the C++0x move-aware containers.  Currently GCC since 4.3 and MSVC 2010 support C++0x 4 7 February 2010
  5. 5. Qt smart pointers  QPointer (4.0)  QSharedDataPointer (4.0)  QExplicitlySharedDataPointer (4.4)  QSharedPointer (4.5)  QWeakPointer (4.5)  QScopedPointer (4.6)  Internal  QtPatternist::AutoPtr (internal class, 4.4)  QGuard (internal class, 4.6) 5 7 February 2010
  6. 6. QPointer  QPointer is a weak pointer class and it shares the pointer value, not the data.  It only operates on QObject and QObject-derived classes.  QPointer has one serious flaw: it lets you know whether the object has been deleted, but it makes no guarantee about the next line! For example, the following code could be in trouble: QPointer<QObject> o = getObject(); // […] if (!o.isNull()) o->setProperty(“objectName”, “Object”);  Even if isNull() returns false, there’s no guarantee that the object won’t get deleted by the next line.  Therefore, QPointer can only be used to access the object if you can guarantee, by external means, that the object won’t get deleted. For example, QWidget and its descendents can only be created, manipulated and deleted in the GUI thread. If your code is running on the GUI thread or has that thread blocked, then QPointer usage is safe. 6 7 February 2010
  7. 7. QSharedDataPointer  The most important of the smart pointer classes in Qt.  It provides implicit sharing, with thread-safe copy-on-write.  The QSharedData class is used as a base class for shared data objects.  QSharedDataPointer requires that the class have a member called ref (see QAtomicInt member in QSharedData class)  The member offers a function called ref() for increasing the reference count and another called deref() that decreases that reference count and returns false when it drops to zero.  QSharedDataPointer members: inline void detach() {if (d && d->ref != 1) detach_helper();} inline T * operator->() {detach(); return d; } inline const T *operator->() const { return d; } private: T *d;  Any non-const access will cause the data to be copied.  The size of a QSharedDataPointer object is exactly the size of a pointer  That means it’s possible to replace normal pointers with it in the code without breaking Binary Compatibility.  This class is the basis of all Qt value-type, implicit-shared, thread-safe copy-on-write recent classes.  The only reason why it isn’t used in the base classes like QByteArray, QString and QList is that those classes were developed before this class was made.  So QSharedDataPointer is a strong smart pointer class, sharing data. 7 7 February 2010
  8. 8. QExplicitlySharedDataPointer  The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object.  This class is exactly like QSharedDataPointer (so it’s a strong smart pointer class, sharing data), with the only difference that it do not do the automatic copy on write operation (detach()) that non-const members of QSharedDataPointer do before allowing the shared data object to be modified.  There is a detach() function available, but if you really want to detach(), you have to call it yourself. This means that QExplicitlySharedDataPointers behave like regular C++ pointers, except that by doing reference counting and not deleting the shared data object until the reference count is 0, they avoid the dangling pointer problem.  QExplicitlySharedDataPointer members: inline void detach() {if (d && d->ref != 1) detach_helper();} inline T *operator->() { return d; } inline const T *operator->() const { return d; } 8 7 February 2010
  9. 9. QSharedDataPointer versus QExplicitlySharedDataPointer class EmployeeData : public QSharedData // can be defined in a separate file { public: EmployeeData() : id(-1) { name.clear(); } EmployeeData(const EmployeeData &other) : QSharedData(other), id(, name( { } ~EmployeeData() {} int id; QString name; }; //------ the public file ------------------------------------------------------ class EmployeeData; // predeclare the private subclass class Employee { public: Employee() { d = new EmployeeData; } Employee(int id, QString name) {d = new EmployeeData(); setId(id); setName(name);} Employee(const Employee &other) : d (other.d) {} void setId(int id) { d->id = id; } void setName(QString name) { d->name = name; } int id() const { return d->id; } QString name() const { return d->name; } private: // a copy constructor or an assignment operator are not needed QSharedDataPointer<EmployeeData> d; }; int main(int argc, char *argv[]) { Employee e1(1001, "Albrecht Durer"); Employee e2 = e1; int i =; e1.setName("Hans Holbein"); // a copy on write is performed for QSharedDataPointer } 9 7 February 2010
  10. 10. QSharedPointer  The QSharedPointer class holds a strong reference to a shared pointer.  The QSharedPointer is an automatic, shared pointer in C++. It behaves exactly like a normal pointer for normal purposes, including respect for constness.  it is polymorphic, it supports static, const, and dynamic casts, it implements atomic reference-counting and thread-safe semantics (it’s only for the pointer itself: remember it shares the pointer, not the data), it supports custom deleters.  QSharedPointer will delete the pointer it is holding when it goes out of scope, provided no other QSharedPointer objects are referencing it.  A QSharedPointer object can be created from a normal pointer, another QSharedPointer object or by promoting a QWeakPointer object to a strong reference.  It comes with a cost, though: to support polymorphism correctly, the size of QSharedPointer is actually twice the size of a normal pointer. This means you cannot maintain binary compatibility while replacing a normal pointer with it in public parts of your API. You can use it internally in your code, though. 10 7 February 2010
  11. 11. QWeakPointer  The QWeakPointer class holds a weak reference to a shared pointer.  The QWeakPointer is an automatic weak reference to a pointer in C++. It cannot be used to dereference the pointer directly, but it can be used to verify if the pointer has been deleted or not in another context.  QWeakPointer objects can only be created by assignment from a QSharedPointer and they let you know when a QSharedPointer has been deleted. QWeakPointer<Data> weak(getSharedPointer()); QSharedPointer<Data> ptr = weak.toStrongRef(); if ( !ptr.isNull() ) ptr->doSomething();  In this case, the promotion of a QWeakPointer to a QSharedPointer will either succeed or it won’t. But that’s a thread- safe decision.  QWeakPointer can be used to track deletion classes derives from QObject. It is more efficient than QPointer, so it should be preferred in all new code. 11 7 February 2010
  12. 12. QScopedPointer  The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction.  It provides a very nice way to do RAII (Resource Acquisition Is Initialization).  It implements a non-shared strong pointer wrapper.  QScopedPointer guarantees that the object pointed to will get deleted when the current scope disappears.  It intentionally has no copy constructor or assignment operator, such that ownership and lifetime is clearly communicated. void myFunction(bool useSubClass) { // assuming that MyClass has a virtual destructor QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass); QScopedPointer<QIODevice> device(handsOverOwnership()); if (m_value > 3) return; process(device); }  QSharedPointer has the size of two pointers.  It also has a custom deleter as a template parameter, as opposed to a parameter to the constructor (like QSharedPointer does): it has no space in those 4 or 8 bytes to store the custom deleter.  QScopedPointer and QExplicitlySharedDataPointer are already used all over the place in the Qt for S60. 12 7 February 2010
  13. 13. References  Pointer (computing)  Smart pointer  C++0x  Introducing QScopedPointer  Count with me: how many smart pointer classes does Qt have? 13 7 February 2010