1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qsharedpointer.h"
44 // to be sure we aren't causing a namespace clash:
45 #include "qshareddata.h"
49 \brief The QSharedPointer class holds a strong reference to a shared pointer
54 The QSharedPointer is an automatic, shared pointer in C++. It
55 behaves exactly like a normal pointer for normal purposes,
56 including respect for constness.
58 QSharedPointer will delete the pointer it is holding when it goes
59 out of scope, provided no other QSharedPointer objects are
62 A QSharedPointer object can be created from a normal pointer,
63 another QSharedPointer object or by promoting a
64 QWeakPointer object to a strong reference.
66 \section1 Thread-Safety
68 QSharedPointer and QWeakPointer are thread-safe and operate
69 atomically on the pointer value. Different threads can also access
70 the QSharedPointer or QWeakPointer pointing to the same object at
71 the same time without need for locking mechanisms.
73 It should be noted that, while the pointer value can be accessed
74 in this manner, QSharedPointer and QWeakPointer provide no
75 guarantee about the object being pointed to. Thread-safety and
76 reentrancy rules for that object still apply.
78 \section1 Other Pointer Classes
80 Qt also provides two other pointer wrapper classes: QPointer and
81 QSharedDataPointer. They are incompatible with one another, since
82 each has its very different use case.
84 QSharedPointer holds a shared pointer by means of an external
85 reference count (i.e., a reference counter placed outside the
86 object). Like its name indicates, the pointer value is shared
87 among all instances of QSharedPointer and QWeakPointer. The
88 contents of the object pointed to by the pointer should not be
89 considered shared, however: there is only one object. For that
90 reason, QSharedPointer does not provide a way to detach or make
91 copies of the pointed object.
93 QSharedDataPointer, on the other hand, holds a pointer to shared
94 data (i.e., a class derived from QSharedData). It does so by means
95 of an internal reference count, placed in the QSharedData base
96 class. This class can, therefore, detach based on the type of
97 access made to the data being guarded: if it's a non-const access,
98 it creates a copy atomically for the operation to complete.
100 QExplicitlySharedDataPointer is a variant of QSharedDataPointer, except
101 that it only detaches if QExplicitlySharedDataPointer::detach() is
102 explicitly called (hence the name).
104 QScopedPointer simply holds a pointer to a heap allocated object and
105 deletes it in its destructor. This class is useful when an object needs to
106 be heap allocated and deleted, but no more. QScopedPointer is lightweight,
107 it makes no use of additional structure or reference counting.
109 Finally, QPointer holds a pointer to a QObject-derived object, but it
110 does so weakly. QPointer can be replaced by QWeakPointer in almost all
111 cases, since they have the same functionality. See
112 \l{QWeakPointer#tracking-qobject} for more information.
114 \section1 Optional pointer tracking
116 A feature of QSharedPointer that can be enabled at compile-time for
117 debugging purposes is a pointer tracking mechanism. When enabled,
118 QSharedPointer registers in a global set all the pointers that it tracks.
119 This allows one to catch mistakes like assigning the same pointer to two
120 QSharedPointer objects.
122 This function is enabled by defining the \tt{QT_SHAREDPOINTER_TRACK_POINTERS}
123 macro before including the QSharedPointer header.
125 It is safe to use this feature even with code compiled without the
126 feature. QSharedPointer will ensure that the pointer is removed from the
127 tracker even from code compiled without pointer tracking.
129 Note, however, that the pointer tracking feature has limitations on
130 multiple- or virtual-inheritance (that is, in cases where two different
131 pointer addresses can refer to the same object). In that case, if a
132 pointer is cast to a different type and its value changes,
133 QSharedPointer's pointer tracking mechanism may fail to detect that the
134 object being tracked is the same.
137 \secton1 QSharedPointer internals
139 QSharedPointer is in reality implemented by two ancestor classes:
140 QtSharedPointer::Basic and QtSharedPointer::ExternalRefCount. The reason
141 for having that split is now mostly legacy: in the beginning,
142 QSharedPointer was meant to support both internal reference counting and
143 external reference counting.
145 QtSharedPointer::Basic implements the basic functionality that is shared
146 between internal- and external-reference counting. That is, it's mostly
147 the accessor functions into QSharedPointer. Those are all inherited by
148 QSharedPointer, which adds another level of shared functionality (the
149 constructors and assignment operators). The Basic class has one member
150 variable, which is the actual pointer being tracked.
152 QtSharedPointer::ExternalRefCount implements the actual reference
153 counting and introduces the d-pointer for QSharedPointer. That d-pointer
154 itself is shared with other QSharedPointer objects as well as
157 The reason for keeping the pointer value itself outside the d-pointer is
158 because of multiple inheritance needs. If you have two QSharedPointer
159 objects of different pointer types, but pointing to the same object in
160 memory, it could happen that the pointer values are different. The \tt
161 differentPointers autotest exemplifies this problem. The same thing could
162 happen in the case of virtual inheritance: a pointer of class matching
163 the virtual base has different address compared to the pointer of the
164 complete object. See the \tt virtualBaseDifferentPointers autotest for
167 The d pointer is of type QtSharedPointer::ExternalRefCountData for simple
168 QSharedPointer objects, but could be of a derived type in some cases. It
169 is basically a reference-counted reference-counter.
172 \section3 QtSharedPointer::ExternalRefCountData
174 This class is basically a reference-counted reference-counter. It has two
175 members: \tt strongref and \tt weakref. The strong reference counter is
176 controlling the lifetime of the object tracked by QSharedPointer. a
177 positive value indicates that the object is alive. It's also the number
178 of QSharedObject instances that are attached to this Data.
180 When the strong reference count decreases to zero, the object is deleted
181 (see below for information on custom deleters). The strong reference
182 count can also exceptionally be -1, indicating that there are no
183 QSharedPointers attached to an object, which is tracked too. The only
184 case where this is possible is that of
185 \l{QWeakPointer#tracking-qobject}{QWeakPointers tracking a QObject}.
187 The weak reference count controls the lifetime of the d-pointer itself.
188 It can be thought of as an internal/intrusive reference count for
189 ExternalRefCountData itself. This count is equal to the number of
190 QSharedPointers and QWeakPointers that are tracking this object. (In case
191 the object tracked derives from QObject, this number is increased by 1,
192 since QObjectPrivate tracks it too).
194 ExternalRefCountData is a virtual class: it has a virtual destructor and
195 a virtual destroy() function. The destroy() function is supposed to
196 delete the object being tracked and return true if it does so. Otherwise,
197 it returns false to indicate that the caller must simply call delete.
198 This allows the normal use-case of QSharedPointer without custom deleters
199 to use only one 12- or 16-byte (depending on whether it's a 32- or 64-bit
200 architecture) external descriptor structure, without paying the price for
201 the custom deleter that it isn't using.
203 \section3 QtSharedPointer::ExternalRefCountDataWithDestroyFn
205 This class is not used directly, per se. It only exists to enable the two
206 classes that derive from it. It adds one member variable, which is a
207 pointer to a function (which returns void and takes an
208 ExternalRefCountData* as a parameter). It also overrides the destroy()
209 function: it calls that function pointer with \tt this as parameter, and
212 That means when ExternalRefCountDataWithDestroyFn is used, the \tt
213 destroyer field must be set to a valid function that \b will delete the
216 This class also adds an operator delete function to ensure that it simply
217 calls the global operator delete. That should be the behaviour in all
218 compilers already, but to be on the safe side, this class ensures that no
219 funny business happens.
221 On a 32-bit architecture, this class is 16 bytes in size, whereas it's 24
222 bytes on 64-bit. (On Itanium where function pointers contain the global
223 pointer, it can be 32 bytes).
225 \section3 QtSharedPointer::ExternalRefCountWithCustomDeleter
227 This class derives from ExternalRefCountDataWithDestroyFn and is a
228 template class. As template parameters, it has the type of the pointer
229 being tracked (\tt T) and a \tt Deleter, which is anything. It adds two
230 fields to its parent class, matching those template parameters: a member
231 of type \tt Deleter and a member of type \tt T*.
233 The purpose of this class is to store the pointer to be deleted and the
234 deleter code along with the d-pointer. This allows the last strong
235 reference to call any arbitrary function that disposes of the object. For
236 example, this allows calling QObject::deleteLater() on a given object.
237 The pointer to the object is kept here to avoid the extra cost of keeping
238 the deleter in the generic case.
240 This class is never instantiated directly: the constructors and
241 destructor are private. Only the create() function may be called to
242 return an object of this type. See below for construction details.
244 The size of this class depends on the size of \tt Deleter. If it's an
245 empty functor (i.e., no members), ABIs generally assign it the size of 1.
246 But given that it's followed by a pointer, up to 3 or 7 padding bytes may
247 be inserted: in that case, the size of this class is 16+4+4 = 24 bytes on
248 32-bit architectures, or 24+8+8 = 40 bytes on 64-bit architectures (48
249 bytes on Itanium with global pointers stored). If \tt Deleter is a
250 function pointer, the size should be the same as the empty structure
251 case, except for Itanium where it may be 56 bytes due to another global
252 pointer. If \tt Deleter is a pointer to a member function (PMF), the size
253 will be even bigger and will depend on the ABI. For architectures using
254 the Itanium C++ ABI, a PMF is twice the size of a normal pointer, or 24
255 bytes on Itanium itself. In that case, the size of this structure will be
256 16+8+4 = 28 bytes on 32-bit architectures, 24+16+8 = 48 bytes on 64-bit,
257 and 32+24+8 = 64 bytes on Itanium.
259 (Values for Itanium consider an LP64 architecture; for ILP32, pointers
260 are 32-bit in length, function pointers are 64-bit and PMF are 96-bit, so
261 the sizes are slightly less)
263 \section3 QtSharedPointer::ExternalRefCountWithContiguousData
265 This class also derives from ExternalRefCountDataWithDestroyFn and it is
266 also a template class. The template parameter is the type \tt T of the
267 class which QSharedPointer tracks. It adds only one member to its parent,
268 which is of type \tt T (the actual type, not a pointer to it).
270 The purpose of this class is to lay the \tt T object out next to the
271 reference counts, saving one memory allocation per shared pointer. This
272 is particularly interesting for small \tt T or for the cases when there
273 are few if any QWeakPointer tracking the object. This class exists to
274 implement the QSharedPointer::create() call.
276 Like ExternalRefCountWithCustomDeleter, this class is never instantiated
277 directly. This class also provides a create() member that returns the
278 pointer, and hides its constructors and destructor. (With C++0x, we'd
281 The size of this class depends on the size of \tt T.
283 \section3 Instantiating ExternalRefCountWithCustomDeleter and ExternalRefCountWithContiguousData
285 Like explained above, these classes have private constructors. Moreover,
286 they are not defined anywhere, so trying to call \tt{new ClassType} would
287 result in a compilation or linker error. Instead, these classes must be
288 constructed via their create() methods.
290 Instead of instantiating the class by the normal way, the create() method
291 calls \tt{operator new} directly with the size of the class, then calls
292 the parent class's constructor only (ExternalRefCountDataWithDestroyFn).
293 This ensures that the inherited members are initialised properly, as well
294 as the virtual table pointer, which must point to
295 ExternalRefCountDataWithDestroyFn's virtual table. That way, we also
296 ensure that the virtual destructor being called is
297 ExternalRefCountDataWithDestroyFn's.
299 After initialising the base class, the
300 ExternalRefCountWithCustomDeleter::create() function initialises the new
301 members directly, by using the placement \tt{operator new}. In the case
302 of the ExternalRefCountWithContiguousData::create() function, the address
303 to the still-uninitialised \tt T member is saved for the callee to use.
304 The member is only initialised in QSharedPointer::create(), so that we
305 avoid having many variants of the internal functions according to the
306 arguments in use for calling the constructor.
308 When initialising the parent class, the create() functions pass the
309 address of the static deleter() member function. That is, when the
310 virtual destroy() is called by QSharedPointer, the deleter() functions
311 are called instead. These functions static_cast the ExternalRefCountData*
312 parameter to their own type and execute their deletion: for the
313 ExternalRefCountWithCustomDeleter::deleter() case, it runs the user's
314 custom deleter, then destroys the deleter; for
315 ExternalRefCountWithContiguousData::deleter, it simply calls the \tt T
318 By not calling the constructor of the derived classes, we avoid
319 instantiating their virtual tables. Since these classes are
320 template-based, there would be one virtual table per \tt T and \tt
321 Deleter type. (This is what Qt 4.5 did.)
323 Instead, only one non-inline function is required per template, which is
324 the deleter() static member. All the other functions can be inlined.
325 What's more, the address of deleter() is calculated only in code, which
326 can be resolved at link-time if the linker can determine that the
327 function lies in the current application or library module (since these
328 classes are not exported, that is the case for Windows or for builds with
329 \tt{-fvisibility=hidden}).
331 In contrast, a virtual table would require at least 3 relocations to be
332 resolved at module load-time, per module where these classes are used.
333 (In the Itanium C++ ABI, there would be more relocations, due to the
336 \section3 Modifications due to pointer-tracking
338 To ensure that pointers created with pointer-tracking enabled get
339 un-tracked when destroyed, even if destroyed by code compiled without the
340 feature, QSharedPointer modifies slightly the instructions of the
343 When ExternalRefCountWithCustomDeleter or
344 ExternalRefCountWithContiguousData are used, their create() functions
345 will set the ExternalRefCountDataWithDestroyFn::destroyer function
346 pointer to safetyCheckDeleter() instead. These static member functions
347 simply call internalSafetyCheckRemove2() before passing control to the
348 normal deleter() function.
350 If neither custom deleter nor QSharedPointer::create() are used, then
351 QSharedPointer uses a custom deleter of its own: the normalDeleter()
352 function, which simply calls \tt delete. By using a custom deleter, the
353 safetyCheckDeleter() procedure described above kicks in.
357 \sa QSharedDataPointer, QWeakPointer, QScopedPointer
362 \brief The QWeakPointer class holds a weak reference to a shared pointer
366 The QWeakPointer is an automatic weak reference to a
367 pointer in C++. It cannot be used to dereference the pointer
368 directly, but it can be used to verify if the pointer has been
369 deleted or not in another context.
371 QWeakPointer objects can only be created by assignment from a
372 QSharedPointer. The exception is pointers derived from QObject: in that
373 case, QWeakPointer serves as a replacement to QPointer.
375 It's important to note that QWeakPointer provides no automatic casting
376 operators to prevent mistakes from happening. Even though QWeakPointer
377 tracks a pointer, it should not be considered a pointer itself, since it
378 doesn't guarantee that the pointed object remains valid.
380 Therefore, to access the pointer that QWeakPointer is tracking, you must
381 first promote it to QSharedPointer and verify if the resulting object is
382 null or not. QSharedPointer guarantees that the object isn't deleted, so
383 if you obtain a non-null object, you may use the pointer. See
384 QWeakPointer::toStrongRef() for an example.
386 QWeakPointer also provides the QWeakPointer::data() method that returns
387 the tracked pointer without ensuring that it remains valid. This function
388 is provided if you can guarantee by external means that the object will
389 not get deleted (or if you only need the pointer value) and the cost of
390 creating a QSharedPointer using toStrongRef() is too high.
392 That function can also be used to obtain the tracked pointer for
393 QWeakPointers that cannot be promoted to QSharedPointer, such as those
394 created directly from a QObject pointer (not via QSharedPointer).
396 \section1 Tracking QObject
398 QWeakPointer can be used to track deletion of classes that derive from QObject,
399 even if they are not managed by QSharedPointer. When used in that role,
400 QWeakPointer replaces the older QPointer in all use-cases. QWeakPointer
401 is also more efficient than QPointer, so it should be preferred in all
404 To do that, QWeakPointer provides a special constructor that is only
405 available if the template parameter \tt T is either QObject or a class
406 deriving from it. Trying to use that constructor if \tt T does not derive
407 from QObject will result in compilation errors.
409 To obtain the QObject being tracked by QWeakPointer, you must use the
410 QWeakPointer::data() function, but only if you can guarantee that the
411 object cannot get deleted by another context. It should be noted that
412 QPointer had the same constraint, so use of QWeakPointer forces you to
413 consider whether the pointer is still valid.
415 QObject-derived classes can only be deleted in the thread they have
416 affinity to (which is the thread they were created in or moved to, using
417 QObject::moveToThread()). In special, QWidget-derived classes cannot be
418 created in non-GUI threads nor moved there. Therefore, guaranteeing that
419 the tracked QObject has affinity to the current thread is enough to also
420 guarantee that it won't be deleted asynchronously.
422 Note that QWeakPointer's size and data layout do not match QPointer, so
423 it cannot replace that class in a binary-compatible manner.
425 Care must also be taken with QWeakPointers created directly from QObject
426 pointers when dealing with code that was compiled with Qt versions prior
427 to 4.6. Those versions may not track the reference counters correctly, so
428 QWeakPointers created from QObject should never be passed to code that
429 hasn't been recompiled.
432 \secton1 QWeakPointer internals
434 QWeakPointer shares most of its internal functionality with
435 \l{QSharedPointer#qsharedpointer-internals}{QSharedPointer}, so see that
436 class's internal documentation for more information.
438 QWeakPointer requires an external reference counter in order to operate.
439 Therefore, it is incompatible by design with \l QSharedData-derived
442 It has a special QObject constructor, which works by calling
443 QtSharedPointer::ExternalRefCountData::getAndRef, which retrieves the
444 d-pointer from QObjectPrivate. If one isn't set yet, that function
445 creates the d-pointer and atomically sets it.
447 If getAndRef needs to create a d-pointer, it sets the strongref to -1,
448 indicating that the QObject is not shared: QWeakPointer is used only to
449 determine whether the QObject has been deleted. In that case, it cannot
450 be upgraded to QSharedPointer (see the previous section).
454 \sa QSharedPointer, QScopedPointer
458 \fn QSharedPointer::QSharedPointer()
460 Creates a QSharedPointer that points to null (0).
464 \fn QSharedPointer::~QSharedPointer()
466 Destroys this QSharedPointer object. If it is the last reference to
467 the pointer stored, this will delete the pointer as well.
471 \fn QSharedPointer::QSharedPointer(T *ptr)
473 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
474 becomes managed by this QSharedPointer and must not be passed to
475 another QSharedPointer object or deleted outside this object.
479 \fn QSharedPointer::QSharedPointer(T *ptr, Deleter deleter)
481 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
482 becomes managed by this QSharedPointer and must not be passed to
483 another QSharedPointer object or deleted outside this object.
485 The \a deleter parameter specifies the custom deleter for this
486 object. The custom deleter is called, instead of the operator delete(),
487 when the strong reference count drops to 0. This is useful,
488 for instance, for calling deleteLater() on a QObject instead:
491 static void doDeleteLater(MyObject *obj)
498 QSharedPointer<MyObject> obj =
499 QSharedPointer<MyObject>(new MyObject, doDeleteLater);
501 // continue using obj
502 obj.clear(); // calls obj->deleteLater();
506 It is also possible to specify a member function directly, as in:
508 QSharedPointer<MyObject> obj =
509 QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);
516 \fn QSharedPointer::QSharedPointer(const QSharedPointer<T> &other)
518 Creates a QSharedPointer object that shares \a other's pointer.
520 If \tt T is a derived type of the template parameter of this class,
521 QSharedPointer will perform an automatic cast. Otherwise, you will
522 get a compiler error.
526 \fn QSharedPointer::QSharedPointer(const QWeakPointer<T> &other)
528 Creates a QSharedPointer by promoting the weak reference \a other
529 to strong reference and sharing its pointer.
531 If \tt T is a derived type of the template parameter of this
532 class, QSharedPointer will perform an automatic cast. Otherwise,
533 you will get a compiler error.
535 \sa QWeakPointer::toStrongRef()
539 \fn QSharedPointer &QSharedPointer::operator=(const QSharedPointer<T> &other)
541 Makes this object share \a other's pointer. The current pointer
542 reference is discarded and, if it was the last, the pointer will
545 If \tt T is a derived type of the template parameter of this
546 class, QSharedPointer will perform an automatic cast. Otherwise,
547 you will get a compiler error.
551 \fn QSharedPointer &QSharedPointer::operator=(const QWeakPointer<T> &other)
553 Promotes \a other to a strong reference and makes this object
554 share a reference to the pointer referenced by it. The current pointer
555 reference is discarded and, if it was the last, the pointer will
558 If \tt T is a derived type of the template parameter of this
559 class, QSharedPointer will perform an automatic cast. Otherwise,
560 you will get a compiler error.
564 \fn T *QSharedPointer::data() const
566 Returns the value of the pointer referenced by this object.
568 Note: do not delete the pointer returned by this function or pass
569 it to another function that could delete it, including creating
570 QSharedPointer or QWeakPointer objects.
574 \fn T &QSharedPointer::operator *() const
576 Provides access to the shared pointer's members.
582 \fn T *QSharedPointer::operator ->() const
584 Provides access to the shared pointer's members.
590 \fn bool QSharedPointer::isNull() const
592 Returns true if this object is holding a reference to a null
597 \fn QSharedPointer::operator bool() const
599 Returns true if this object is not null. This function is suitable
600 for use in \tt if-constructs, like:
603 if (sharedptr) { ... }
610 \fn bool QSharedPointer::operator !() const
612 Returns true if this object is null. This function is suitable
613 for use in \tt if-constructs, like:
616 if (!sharedptr) { ... }
623 \fn QSharedPointer<X> QSharedPointer::staticCast() const
625 Performs a static cast from this pointer's type to \tt X and returns
626 a QSharedPointer that shares the reference. This function can be
627 used for up- and for down-casting, but is more useful for
630 Note: the template type \c X must have the same const and volatile
631 qualifiers as the template of this object, or the cast will
632 fail. Use constCast() if you need to drop those qualifiers.
634 \sa dynamicCast(), constCast(), qSharedPointerCast()
638 \fn QSharedPointer<X> QSharedPointer::dynamicCast() const
640 Performs a dynamic cast from this pointer's type to \tt X and
641 returns a QSharedPointer that shares the reference. If this
642 function is used to up-cast, then QSharedPointer will perform a \tt
643 dynamic_cast, which means that if the object being pointed by this
644 QSharedPointer is not of type \tt X, the returned object will be
647 Note: the template type \c X must have the same const and volatile
648 qualifiers as the template of this object, or the cast will
649 fail. Use constCast() if you need to drop those qualifiers.
651 \sa qSharedPointerDynamicCast()
655 \fn QSharedPointer<X> QSharedPointer::constCast() const
657 Performs a \tt const_cast from this pointer's type to \tt X and returns
658 a QSharedPointer that shares the reference. This function can be
659 used for up- and for down-casting, but is more useful for
662 \sa isNull(), qSharedPointerConstCast()
666 \fn QSharedPointer<X> QSharedPointer::objectCast() const
669 Performs a \l qobject_cast() from this pointer's type to \tt X and
670 returns a QSharedPointer that shares the reference. If this
671 function is used to up-cast, then QSharedPointer will perform a \tt
672 qobject_cast, which means that if the object being pointed by this
673 QSharedPointer is not of type \tt X, the returned object will be
676 Note: the template type \c X must have the same const and volatile
677 qualifiers as the template of this object, or the cast will
678 fail. Use constCast() if you need to drop those qualifiers.
680 \sa qSharedPointerObjectCast()
684 \fn QWeakPointer<T> QSharedPointer::toWeakRef() const
686 Returns a weak reference object that shares the pointer referenced
689 \sa QWeakPointer::QWeakPointer()
693 \fn void QSharedPointer::clear()
695 Clears this QSharedPointer object, dropping the reference that it
696 may have had to the pointer. If this was the last reference, then
697 the pointer itself will be deleted.
701 \fn void QSharedPointer::reset()
704 Same as clear(). For std::shared_ptr compatibility.
708 \fn void QSharedPointer::reset(T *t)
711 Resets this QSharedPointer object to point to \a t
712 instead. Equivalent to:
714 QSharedPointer<T> other(t); this->swap(other);
719 \fn void QSharedPointer::reset(T *t, Deleter deleter)
722 Resets this QSharedPointer object to point to \a t
723 instead, with deleter \a deleter. Equivalent to:
725 QSharedPointer<T> other(t, deleter); this->swap(other);
730 \fn QWeakPointer::QWeakPointer()
732 Creates a QWeakPointer that points to nothing.
736 \fn QWeakPointer::~QWeakPointer()
738 Destroys this QWeakPointer object. The pointer referenced
739 by this object will not be deleted.
743 \fn QWeakPointer::QWeakPointer(const QWeakPointer<T> &other)
745 Creates a QWeakPointer that holds a weak reference to the
746 pointer referenced by \a other.
748 If \tt T is a derived type of the template parameter of this
749 class, QWeakPointer will perform an automatic cast. Otherwise,
750 you will get a compiler error.
754 \fn QWeakPointer::QWeakPointer(const QSharedPointer<T> &other)
756 Creates a QWeakPointer that holds a weak reference to the
757 pointer referenced by \a other.
759 If \tt T is a derived type of the template parameter of this
760 class, QWeakPointer will perform an automatic cast. Otherwise,
761 you will get a compiler error.
765 \fn QWeakPointer::QWeakPointer(const QObject *obj)
768 Creates a QWeakPointer that holds a weak reference directly to the
769 QObject \a obj. This constructor is only available if the template type
770 \tt T is QObject or derives from it (otherwise a compilation error will
773 You can use this constructor with any QObject, even if they were not
774 created with \l QSharedPointer.
776 Note that QWeakPointers created this way on arbitrary QObjects usually
777 cannot be promoted to QSharedPointer.
779 \sa QSharedPointer, QWeakPointer#tracking-qobject
783 \fn QWeakPointer &QWeakPointer::operator=(const QObject *obj)
786 Makes this QWeakPointer hold a weak reference directly to the QObject
787 \a obj. This function is only available if the template type \tt T is
788 QObject or derives from it.
790 \sa QWeakPointer#tracking-qobject
794 \fn QWeakPointer &QWeakPointer::operator=(const QWeakPointer<T> &other)
796 Makes this object share \a other's pointer. The current pointer
797 reference is discarded but is not deleted.
799 If \tt T is a derived type of the template parameter of this
800 class, QWeakPointer will perform an automatic cast. Otherwise,
801 you will get a compiler error.
805 \fn QWeakPointer &QWeakPointer::operator=(const QSharedPointer<T> &other)
807 Makes this object share \a other's pointer. The current pointer
808 reference is discarded but is not deleted.
810 If \tt T is a derived type of the template parameter of this
811 class, QWeakPointer will perform an automatic cast. Otherwise,
812 you will get a compiler error.
816 \fn bool QWeakPointer::isNull() const
818 Returns true if this object is holding a reference to a null
821 Note that, due to the nature of weak references, the pointer that
822 QWeakPointer references can become null at any moment, so
823 the value returned from this function can change from false to
824 true from one call to the next.
828 \fn QWeakPointer::operator bool() const
830 Returns true if this object is not null. This function is suitable
831 for use in \tt if-constructs, like:
837 Note that, due to the nature of weak references, the pointer that
838 QWeakPointer references can become null at any moment, so
839 the value returned from this function can change from true to
840 false from one call to the next.
846 \fn bool QWeakPointer::operator !() const
848 Returns true if this object is null. This function is suitable
849 for use in \tt if-constructs, like:
852 if (!weakref) { ... }
855 Note that, due to the nature of weak references, the pointer that
856 QWeakPointer references can become null at any moment, so
857 the value returned from this function can change from false to
858 true from one call to the next.
864 \fn T *QWeakPointer::data() const
867 Returns the value of the pointer being tracked by this QWeakPointer,
868 \b without ensuring that it cannot get deleted. To have that guarantee,
869 use toStrongRef(), which returns a QSharedPointer object. If this
870 function can determine that the pointer has already been deleted, it
873 It is ok to obtain the value of the pointer and using that value itself,
874 like for example in debugging statements:
877 qDebug("Tracking %p", weakref.data());
880 However, dereferencing the pointer is only allowed if you can guarantee
881 by external means that the pointer does not get deleted. For example,
882 if you can be certain that no other thread can delete it, nor the
883 functions that you may call.
885 If that is the case, then the following code is valid:
888 // this pointer cannot be used in another thread
889 // so other threads cannot delete it
890 QWeakPointer<int> weakref = obtainReference();
892 Object *obj = weakref.data();
894 // if the pointer wasn't deleted yet, we know it can't get
895 // deleted by our own code here nor the functions we call
900 Use this function with care.
902 \sa isNull(), toStrongRef()
906 \fn QSharedPointer<T> QWeakPointer::toStrongRef() const
908 Promotes this weak reference to a strong one and returns a
909 QSharedPointer object holding that reference. When promoting to
910 QSharedPointer, this function verifies if the object has been deleted
911 already or not. If it hasn't, this function increases the reference
912 count to the shared object, thus ensuring that it will not get
915 Since this function can fail to obtain a valid strong reference to the
916 shared object, you should always verify if the conversion succeeded,
917 by calling QSharedPointer::isNull() on the returned object.
919 For example, the following code promotes a QWeakPointer that was held
920 to a strong reference and, if it succeeded, it prints the value of the
921 integer that was held:
924 QWeakPointer<int> weakref;
928 QSharedPointer<int> strong = weakref.toStrongRef();
930 qDebug() << "The value is:" << *strong;
932 qDebug() << "The value has already been deleted";
935 \sa QSharedPointer::QSharedPointer()
939 \fn void QWeakPointer::clear()
941 Clears this QWeakPointer object, dropping the reference that it
942 may have had to the pointer.
946 \fn bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
947 \relates QSharedPointer
949 Returns true if the pointer referenced by \a ptr1 is the
950 same pointer as that referenced by \a ptr2.
952 If \a ptr2's template parameter is different from \a ptr1's,
953 QSharedPointer will attempt to perform an automatic \tt static_cast
954 to ensure that the pointers being compared are equal. If \a ptr2's
955 template parameter is not a base or a derived type from
956 \a ptr1's, you will get a compiler error.
960 \fn bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
961 \relates QSharedPointer
963 Returns true if the pointer referenced by \a ptr1 is not the
964 same pointer as that referenced by \a ptr2.
966 If \a ptr2's template parameter is different from \a ptr1's,
967 QSharedPointer will attempt to perform an automatic \tt static_cast
968 to ensure that the pointers being compared are equal. If \a ptr2's
969 template parameter is not a base or a derived type from
970 \a ptr1's, you will get a compiler error.
974 \fn bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
975 \relates QSharedPointer
977 Returns true if the pointer referenced by \a ptr1 is the
978 same pointer as \a ptr2.
980 If \a ptr2's type is different from \a ptr1's,
981 QSharedPointer will attempt to perform an automatic \tt static_cast
982 to ensure that the pointers being compared are equal. If \a ptr2's
983 type is not a base or a derived type from this
984 \a ptr1's, you will get a compiler error.
988 \fn bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
989 \relates QSharedPointer
991 Returns true if the pointer referenced by \a ptr1 is not the
992 same pointer as \a ptr2.
994 If \a ptr2's type is different from \a ptr1's,
995 QSharedPointer will attempt to perform an automatic \tt static_cast
996 to ensure that the pointers being compared are equal. If \a ptr2's
997 type is not a base or a derived type from this
998 \a ptr1's, you will get a compiler error.
1002 \fn bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
1003 \relates QSharedPointer
1005 Returns true if the pointer \a ptr1 is the
1006 same pointer as that referenced by \a ptr2.
1008 If \a ptr2's template parameter is different from \a ptr1's type,
1009 QSharedPointer will attempt to perform an automatic \tt static_cast
1010 to ensure that the pointers being compared are equal. If \a ptr2's
1011 template parameter is not a base or a derived type from
1012 \a ptr1's type, you will get a compiler error.
1016 \fn bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
1017 \relates QSharedPointer
1019 Returns true if the pointer \a ptr1 is not the
1020 same pointer as that referenced by \a ptr2.
1022 If \a ptr2's template parameter is different from \a ptr1's type,
1023 QSharedPointer will attempt to perform an automatic \tt static_cast
1024 to ensure that the pointers being compared are equal. If \a ptr2's
1025 template parameter is not a base or a derived type from
1026 \a ptr1's type, you will get a compiler error.
1030 \fn bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1031 \relates QWeakPointer
1033 Returns true if the pointer referenced by \a ptr1 is the
1034 same pointer as that referenced by \a ptr2.
1036 If \a ptr2's template parameter is different from \a ptr1's,
1037 QSharedPointer will attempt to perform an automatic \tt static_cast
1038 to ensure that the pointers being compared are equal. If \a ptr2's
1039 template parameter is not a base or a derived type from
1040 \a ptr1's, you will get a compiler error.
1044 \fn bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1045 \relates QWeakPointer
1047 Returns true if the pointer referenced by \a ptr1 is not the
1048 same pointer as that referenced by \a ptr2.
1050 If \a ptr2's template parameter is different from \a ptr1's,
1051 QSharedPointer will attempt to perform an automatic \tt static_cast
1052 to ensure that the pointers being compared are equal. If \a ptr2's
1053 template parameter is not a base or a derived type from
1054 \a ptr1's, you will get a compiler error.
1058 \fn bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1059 \relates QWeakPointer
1061 Returns true if the pointer referenced by \a ptr1 is the
1062 same pointer as that referenced by \a ptr2.
1064 If \a ptr2's template parameter is different from \a ptr1's,
1065 QSharedPointer will attempt to perform an automatic \tt static_cast
1066 to ensure that the pointers being compared are equal. If \a ptr2's
1067 template parameter is not a base or a derived type from
1068 \a ptr1's, you will get a compiler error.
1072 \fn bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1073 \relates QWeakPointer
1075 Returns true if the pointer referenced by \a ptr1 is not the
1076 same pointer as that referenced by \a ptr2.
1078 If \a ptr2's template parameter is different from \a ptr1's,
1079 QSharedPointer will attempt to perform an automatic \tt static_cast
1080 to ensure that the pointers being compared are equal. If \a ptr2's
1081 template parameter is not a base or a derived type from
1082 \a ptr1's, you will get a compiler error.
1086 \fn QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
1087 \relates QSharedPointer
1089 Returns a shared pointer to the pointer held by \a other, cast to
1090 type \tt X. The types \tt T and \tt X must belong to one
1091 hierarchy for the \tt static_cast to succeed.
1093 Note that \tt X must have the same cv-qualifiers (\tt const and
1094 \tt volatile) that \tt T has, or the code will fail to
1095 compile. Use qSharedPointerConstCast to cast away the constness.
1097 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1101 \fn QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
1102 \relates QSharedPointer
1103 \relates QWeakPointer
1105 Returns a shared pointer to the pointer held by \a other, cast to
1106 type \tt X. The types \tt T and \tt X must belong to one
1107 hierarchy for the \tt static_cast to succeed.
1109 The \a other object is converted first to a strong reference. If
1110 that conversion fails (because the object it's pointing to has
1111 already been deleted), this function returns a null
1114 Note that \tt X must have the same cv-qualifiers (\tt const and
1115 \tt volatile) that \tt T has, or the code will fail to
1116 compile. Use qSharedPointerConstCast to cast away the constness.
1118 \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1122 \fn QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &other)
1123 \relates QSharedPointer
1125 Returns a shared pointer to the pointer held by \a other, using a
1126 dynamic cast to type \tt X to obtain an internal pointer of the
1127 appropriate type. If the \tt dynamic_cast fails, the object
1128 returned will be null.
1130 Note that \tt X must have the same cv-qualifiers (\tt const and
1131 \tt volatile) that \tt T has, or the code will fail to
1132 compile. Use qSharedPointerConstCast to cast away the constness.
1134 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1138 \fn QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &other)
1139 \relates QSharedPointer
1140 \relates QWeakPointer
1142 Returns a shared pointer to the pointer held by \a other, using a
1143 dynamic cast to type \tt X to obtain an internal pointer of the
1144 appropriate type. If the \tt dynamic_cast fails, the object
1145 returned will be null.
1147 The \a other object is converted first to a strong reference. If
1148 that conversion fails (because the object it's pointing to has
1149 already been deleted), this function also returns a null
1152 Note that \tt X must have the same cv-qualifiers (\tt const and
1153 \tt volatile) that \tt T has, or the code will fail to
1154 compile. Use qSharedPointerConstCast to cast away the constness.
1156 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1160 \fn QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &other)
1161 \relates QSharedPointer
1163 Returns a shared pointer to the pointer held by \a other, cast to
1164 type \tt X. The types \tt T and \tt X must belong to one
1165 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1166 volatile differences between \tt T and \tt X are ignored.
1168 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1172 \fn QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &other)
1173 \relates QSharedPointer
1174 \relates QWeakPointer
1176 Returns a shared pointer to the pointer held by \a other, cast to
1177 type \tt X. The types \tt T and \tt X must belong to one
1178 hierarchy for the \tt const_cast to succeed. The \tt const and
1179 \tt volatile differences between \tt T and \tt X are ignored.
1181 The \a other object is converted first to a strong reference. If
1182 that conversion fails (because the object it's pointing to has
1183 already been deleted), this function returns a null
1186 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
1190 \fn QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &other)
1191 \relates QSharedPointer
1194 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1196 Returns a shared pointer to the pointer held by \a other, using a
1197 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1198 appropriate type. If the \tt qobject_cast fails, the object
1199 returned will be null.
1201 Note that \tt X must have the same cv-qualifiers (\tt const and
1202 \tt volatile) that \tt T has, or the code will fail to
1203 compile. Use qSharedPointerConstCast to cast away the constness.
1205 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1209 \fn QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &other)
1210 \relates QSharedPointer
1211 \relates QWeakPointer
1214 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1216 Returns a shared pointer to the pointer held by \a other, using a
1217 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1218 appropriate type. If the \tt qobject_cast fails, the object
1219 returned will be null.
1221 The \a other object is converted first to a strong reference. If
1222 that conversion fails (because the object it's pointing to has
1223 already been deleted), this function also returns a null
1226 Note that \tt X must have the same cv-qualifiers (\tt const and
1227 \tt volatile) that \tt T has, or the code will fail to
1228 compile. Use qSharedPointerConstCast to cast away the constness.
1230 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1235 \fn QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &other)
1236 \relates QWeakPointer
1238 Returns a weak pointer to the pointer held by \a other, cast to
1239 type \tt X. The types \tt T and \tt X must belong to one
1240 hierarchy for the \tt static_cast to succeed.
1242 Note that \tt X must have the same cv-qualifiers (\tt const and
1243 \tt volatile) that \tt T has, or the code will fail to
1244 compile. Use qSharedPointerConstCast to cast away the constness.
1250 #if !defined(QT_NO_QOBJECT)
1251 #include "private/qobject_p.h"
1257 This function is called for a just-created QObject \a obj, to enable
1258 the use of QSharedPointer and QWeakPointer in the future.
1260 void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1265 This function is called when a QSharedPointer is created from a QWeakPointer
1267 We check that the QWeakPointer was really created from a QSharedPointer, and
1270 void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1272 if (strongref.load() < 0)
1273 qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1276 QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1279 QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
1280 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1282 ExternalRefCountData *that = d->sharedRefcount.load();
1284 that->weakref.ref();
1288 // we can create the refcount data because it doesn't exist
1289 ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
1290 x->strongref.store(-1);
1291 x->weakref.store(2); // the QWeakPointer that called us plus the QObject itself
1292 if (!d->sharedRefcount.testAndSetRelease(0, x)) {
1294 x = d->sharedRefcount.loadAcquire();
1306 //# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1307 # ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1308 # if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1309 # define BACKTRACE_SUPPORTED
1310 # elif defined(Q_OS_MACX)
1311 # define BACKTRACE_SUPPORTED
1315 # if defined(BACKTRACE_SUPPORTED)
1316 # include <sys/types.h>
1317 # include <execinfo.h>
1319 # include <unistd.h>
1320 # include <sys/wait.h>
1324 static inline QByteArray saveBacktrace() __attribute__((always_inline));
1325 static inline QByteArray saveBacktrace()
1327 static const int maxFrames = 32;
1329 QByteArray stacktrace;
1330 stacktrace.resize(sizeof(void*) * maxFrames);
1331 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1332 stacktrace.resize(sizeof(void*) * stack_size);
1337 static void printBacktrace(QByteArray stacktrace)
1339 void *const *stack = (void *const *)stacktrace.constData();
1340 int stack_size = stacktrace.size() / sizeof(void*);
1341 char **stack_symbols = backtrace_symbols(stack, stack_size);
1345 if (pipe(filter) != -1)
1349 dup2(fileno(stderr), fileno(stdout));
1350 dup2(filter[0], fileno(stdin));
1353 execlp("c++filt", "c++filt", "-n", NULL);
1356 execl("/bin/cat", "/bin/cat", NULL);
1368 output = fdopen(filter[1], "w");
1371 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1372 for (int i = 0; i < stack_size; ++i) {
1373 if (strlen(stack_symbols[i]))
1374 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1376 fprintf(output, "#%-2d %p\n", i, stack[i]);
1381 waitpid(child, 0, 0);
1387 # endif // BACKTRACE_SUPPORTED
1392 const volatile void *pointer;
1393 # ifdef BACKTRACE_SUPPORTED
1394 QByteArray backtrace;
1402 QHash<const void *, Data> dPointers;
1403 QHash<const volatile void *, const void *> dataPointers;
1407 Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1411 namespace QtSharedPointer {
1412 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1418 void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1420 KnownPointers *const kp = knownPointers();
1422 return; // end-game: the application is being destroyed already
1424 QMutexLocker lock(&kp->mutex);
1425 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1427 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1429 const void *other_d_ptr = kp->dataPointers.value(ptr, 0);
1431 # ifdef BACKTRACE_SUPPORTED
1432 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1434 qFatal("QSharedPointer: internal self-check failed: pointer %p was already tracked "
1435 "by another QSharedPointer object %p", ptr, other_d_ptr);
1440 # ifdef BACKTRACE_SUPPORTED
1441 data.backtrace = saveBacktrace();
1444 kp->dPointers.insert(d_ptr, data);
1445 kp->dataPointers.insert(ptr, d_ptr);
1446 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1452 void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1454 KnownPointers *const kp = knownPointers();
1456 return; // end-game: the application is being destroyed already
1458 QMutexLocker lock(&kp->mutex);
1460 QHash<const void *, Data>::iterator it = kp->dPointers.find(d_ptr);
1461 if (it == kp->dPointers.end()) {
1462 qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1463 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1464 "in your code.", d_ptr);
1467 QHash<const volatile void *, const void *>::iterator it2 = kp->dataPointers.find(it->pointer);
1468 Q_ASSERT(it2 != kp->dataPointers.end());
1470 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1473 kp->dataPointers.erase(it2);
1474 kp->dPointers.erase(it);
1475 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1480 Called by the QSharedPointer autotest
1482 void QtSharedPointer::internalSafetyCheckCleanCheck()
1484 # ifdef QT_BUILD_INTERNAL
1485 KnownPointers *const kp = knownPointers();
1486 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1488 if (kp->dPointers.size() != kp->dataPointers.size())
1489 qFatal("Internal consistency error: the number of pointers is not equal!");
1491 if (!kp->dPointers.isEmpty())
1492 qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size());