1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2020 Intel Corporation.
3// Copyright (C) 2019 Klarälvdalens Datakonsult AB.
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#include "qsharedpointer.h"
7
8// to be sure we aren't causing a namespace clash:
9#include "qshareddata.h"
10
11/*!
12 \class QSharedPointer
13 \inmodule QtCore
14 \brief The QSharedPointer class holds a strong reference to a shared pointer.
15 \since 4.5
16
17 \reentrant
18
19 The QSharedPointer is an automatic, shared pointer in C++. It
20 behaves exactly like a normal pointer for normal purposes,
21 including respect for constness.
22
23 QSharedPointer will delete the pointer it is holding when it goes
24 out of scope, provided no other QSharedPointer objects are
25 referencing it.
26
27 A QSharedPointer object can be created from a normal pointer,
28 another QSharedPointer object or by promoting a
29 QWeakPointer object to a strong reference.
30
31 \section1 Thread-Safety
32
33 QSharedPointer and QWeakPointer are reentrant classes. This means that, in
34 general, a given QSharedPointer or QWeakPointer object \b{cannot} be
35 accessed by multiple threads at the same time without synchronization.
36
37 Different QSharedPointer and QWeakPointer objects can safely be accessed
38 by multiple threads at the same time. This includes the case where they
39 hold pointers to the same object; the reference counting mechanism
40 is atomic, and no manual synchronization is required.
41
42 It should be noted that, while the pointer value can be accessed in this
43 manner (that is, by multiple threads at the same time, without
44 synchronization), QSharedPointer and QWeakPointer provide no guarantee
45 about the object being pointed to. The specific thread-safety and
46 reentrancy rules for that object still apply.
47
48 \section1 Other Pointer Classes
49
50 Qt also provides two other pointer wrapper classes: QPointer and
51 QSharedDataPointer. They are incompatible with one another, since
52 each has its very different use case.
53
54 QSharedPointer holds a shared pointer by means of an external
55 reference count (i.e., a reference counter placed outside the
56 object). Like its name indicates, the pointer value is shared
57 among all instances of QSharedPointer and QWeakPointer. The
58 contents of the object pointed to by the pointer should not be
59 considered shared, however: there is only one object. For that
60 reason, QSharedPointer does not provide a way to detach or make
61 copies of the pointed object.
62
63 QSharedDataPointer, on the other hand, holds a pointer to shared
64 data (i.e., a class derived from QSharedData). It does so by means
65 of an internal reference count, placed in the QSharedData base
66 class. This class can, therefore, detach based on the type of
67 access made to the data being guarded: if it's a non-const access,
68 it creates a copy atomically for the operation to complete.
69
70 QExplicitlySharedDataPointer is a variant of QSharedDataPointer, except
71 that it only detaches if QExplicitlySharedDataPointer::detach() is
72 explicitly called (hence the name).
73
74 QScopedPointer simply holds a pointer to a heap allocated object and
75 deletes it in its destructor. This class is useful when an object needs to
76 be heap allocated and deleted, but no more. QScopedPointer is lightweight,
77 it makes no use of additional structure or reference counting.
78
79 Finally, QPointer holds a pointer to a QObject-derived object, but it
80 does so weakly. QWeakPointer has the same functionality, but its use for
81 that function is deprecated.
82
83 \section1 Optional Pointer Tracking
84
85 A feature of QSharedPointer that can be enabled at compile-time for
86 debugging purposes is a pointer tracking mechanism. When enabled,
87 QSharedPointer registers in a global set all the pointers that it tracks.
88 This allows one to catch mistakes like assigning the same pointer to two
89 QSharedPointer objects.
90
91 This function is enabled by defining the \tt{QT_SHAREDPOINTER_TRACK_POINTERS}
92 macro before including the QSharedPointer header.
93
94 It is safe to use this feature even with code compiled without the
95 feature. QSharedPointer will ensure that the pointer is removed from the
96 tracker even from code compiled without pointer tracking.
97
98 Note, however, that the pointer tracking feature has limitations on
99 multiple- or virtual-inheritance (that is, in cases where two different
100 pointer addresses can refer to the same object). In that case, if a
101 pointer is cast to a different type and its value changes,
102 QSharedPointer's pointer tracking mechanism may fail to detect that the
103 object being tracked is the same.
104
105 \omit
106 \section1 QSharedPointer internals
107
108 QSharedPointer has two "private" members: the pointer itself being tracked
109 and a d-pointer. Those members are private to the class, but QSharedPointer
110 is friends with QWeakPointer and other QSharedPointer with different
111 template arguments. (On some compilers, template friends are not supported,
112 so the members are technically public)
113
114 The reason for keeping the pointer value itself outside the d-pointer is
115 because of multiple inheritance needs. If you have two QSharedPointer
116 objects of different pointer types, but pointing to the same object in
117 memory, it could happen that the pointer values are different. The \tt
118 differentPointers autotest exemplifies this problem. The same thing could
119 happen in the case of virtual inheritance: a pointer of class matching
120 the virtual base has different address compared to the pointer of the
121 complete object. See the \tt virtualBaseDifferentPointers autotest for
122 this problem.
123
124 The d pointer is a pointer to QtSharedPointer::ExternalRefCountData, but it
125 always points to one of the two classes derived from ExternalRefCountData.
126
127 \section2 d-pointer
128 \section3 QtSharedPointer::ExternalRefCountData
129
130 It is basically a reference-counted reference-counter plus a pointer to the
131 function to be used to delete the pointer. It has three members: \tt
132 strongref, \tt weakref, and \tt destroyer. The strong reference counter is
133 controlling the lifetime of the object tracked by QSharedPointer. A
134 positive value indicates that the object is alive. It's also the number of
135 QSharedObject instances that are attached to this Data.
136
137 When the strong reference count decreases to zero, the object is deleted
138 (see below for information on custom deleters). The strong reference count
139 can also exceptionally be -1, indicating that there are no QSharedPointers
140 attached to an object, which is tracked too. The only case where this is
141 possible is that of QWeakPointers and QPointers tracking a QObject. Note
142 that QWeakPointers tracking a QObject is deprecated.
143
144 The weak reference count controls the lifetime of the d-pointer itself.
145 It can be thought of as an internal/intrusive reference count for
146 ExternalRefCountData itself. This count is equal to the number of
147 QSharedPointers and QWeakPointers that are tracking this object. In case
148 the object is a QObject being tracked by QPointer, this number is increased
149 by 1, since QObjectPrivate tracks it too.
150
151 The third member is a pointer to the function that is used to delete the
152 pointer being tracked. That happens when the destroy() function is called.
153
154 The size of this class is the size of the two atomic ints plus the size of
155 a pointer. On 32-bit architectures, that's 12 bytes, whereas on 64-bit ones
156 it's 16 bytes. There is no padding.
157
158 \section3 QtSharedPointer::ExternalRefCountWithCustomDeleter
159
160 This class derives from ExternalRefCountData and is a template class. As
161 template parameters, it has the type of the pointer being tracked (\tt T)
162 and a \tt Deleter, which is anything. It adds two fields to its parent
163 class, matching those template parameters: a member of type \tt Deleter and
164 a member of type \tt T*. Those members are actually inside a template
165 struct of type CustomDeleter, which is partially-specialized for normal
166 deletion. See below for more details on that.
167
168 The purpose of this class is to store the pointer to be deleted and the
169 deleter code along with the d-pointer. This allows the last strong
170 reference to call any arbitrary function that disposes of the object. For
171 example, this allows calling QObject::deleteLater() on a given object.
172 The pointer to the object is kept here because it needs to match the actual
173 deleter function's parameters, regardless of what template argument the
174 last QSharedPointer instance had.
175
176 This class is never instantiated directly: the constructors and
177 destructor are deleted. Only the create() function
178 may be called to return an object of this type. See below for construction
179 details.
180
181 The size of this class depends on the size of \tt Deleter. If it's an empty
182 functor (i.e., no members), ABIs generally assign it the size of 1. But
183 given that it's followed by a pointer, padding bytes may be inserted so
184 that the alignment of the class and of the pointer are correct. In that
185 case, the size of this class is 12+4+4 = 20 bytes on 32-bit architectures,
186 or 16+8+8 = 40 bytes on 64-bit architectures. If \tt Deleter is a function
187 pointer, the size should be the same as the empty structure case. If \tt
188 Deleter is a pointer to a member function (PMF), the size will be bigger
189 and will depend on the ABI. For architectures using the Itanium C++ ABI, a
190 PMF is twice the size of a normal pointer. In that case, the size of this
191 structure will be 12+8+4 = 24 bytes on 32-bit architectures, 16+16+8 = 40
192 bytes on 64-bit ones.
193
194 If the deleter was not specified when creating the QSharedPointer object
195 (i.e., if a standard \tt delete call is expected), then there's an
196 optimization that avoids the need to store another function pointer in
197 ExternalRefCountWithCustomDeleter. Instead, a template specialization makes
198 a direct delete call. The size of the structure, in this case, is 12+4 = 16
199 bytes on 32-bit architectures, 16+8 = 24 bytes on 64-bit ones.
200
201 \section3 QtSharedPointer::ExternalRefCountWithContiguousData
202
203 This class also derives from ExternalRefCountData and it is
204 also a template class. The template parameter is the type \tt T of the
205 class which QSharedPointer tracks. It adds only one member to its parent,
206 which is of type \tt T (the actual type, not a pointer to it).
207
208 The purpose of this class is to lay the \tt T object out next to the
209 reference counts, saving one memory allocation per shared pointer. This
210 is particularly interesting for small \tt T or for the cases when there
211 are few if any QWeakPointer tracking the object. This class exists to
212 implement the QSharedPointer::create() call.
213
214 Like ExternalRefCountWithCustomDeleter, this class is never instantiated
215 directly. This class also provides a create() member that returns the
216 pointer, and deletes its constructors and destructor.
217
218 The size of this class depends on the size of \tt T.
219
220 \section3 Instantiating ExternalRefCountWithCustomDeleter and ExternalRefCountWithContiguousData
221
222 Like explained above, these classes have private constructors. Moreover,
223 they are not defined anywhere, so trying to call \tt{new ClassType} would
224 result in a compilation or linker error. Instead, these classes must be
225 constructed via their create() methods.
226
227 Instead of instantiating the class by the normal way, the create() method
228 calls \tt{operator new} directly with the size of the class, then calls
229 the parent class's constructor only (that is, ExternalRefCountData's constructor).
230 This ensures that the inherited members are initialised properly.
231
232 After initialising the base class, the
233 ExternalRefCountWithCustomDeleter::create() function initialises the new
234 members directly, by using the placement \tt{operator new}. In the case
235 of the ExternalRefCountWithContiguousData::create() function, the address
236 to the still-uninitialised \tt T member is saved for the callee to use.
237 The member is only initialised in QSharedPointer::create(), so that we
238 avoid having many variants of the internal functions according to the
239 arguments in use for calling the constructor.
240
241 When initialising the parent class, the create() functions pass the
242 address of the static deleter() member function. That is, when the
243 destroy() function is called by QSharedPointer, the deleter() functions
244 are called instead. These functions static_cast the ExternalRefCountData*
245 parameter to their own type and execute their deletion: for the
246 ExternalRefCountWithCustomDeleter::deleter() case, it runs the user's
247 custom deleter, then destroys the deleter; for
248 ExternalRefCountWithContiguousData::deleter, it simply calls the \tt T
249 destructor directly.
250
251 Only one non-inline function is required per template, which is
252 the deleter() static member. All the other functions can be inlined.
253 What's more, the address of deleter() is calculated only in code, which
254 can be resolved at link-time if the linker can determine that the
255 function lies in the current application or library module (since these
256 classes are not exported, that is the case for Windows or for builds with
257 \tt{-fvisibility=hidden}).
258
259 \section3 Modifications due to pointer-tracking
260
261 To ensure that pointers created with pointer-tracking enabled get
262 un-tracked when destroyed, even if destroyed by code compiled without the
263 feature, QSharedPointer modifies slightly the instructions of the
264 previous sections.
265
266 When ExternalRefCountWithCustomDeleter or
267 ExternalRefCountWithContiguousData are used, their create() functions
268 will set the ExternalRefCountData::destroyer function
269 pointer to safetyCheckDeleter() instead. These static member functions
270 simply call internalSafetyCheckRemove() before passing control to the
271 normal deleter() function.
272
273 If neither custom deleter nor QSharedPointer::create() are used, then
274 QSharedPointer uses a custom deleter of its own: the normalDeleter()
275 function, which simply calls \tt delete. By using a custom deleter, the
276 safetyCheckDeleter() procedure described above kicks in.
277
278 \endomit
279
280 \sa QSharedDataPointer, QWeakPointer, QScopedPointer, QEnableSharedFromThis
281*/
282
283/*!
284 \class QWeakPointer
285 \inmodule QtCore
286 \brief The QWeakPointer class holds a weak reference to a shared pointer.
287 \since 4.5
288 \reentrant
289
290 The QWeakPointer is an automatic weak reference to a
291 pointer in C++. It cannot be used to dereference the pointer
292 directly, but it can be used to verify if the pointer has been
293 deleted or not in another context.
294
295 QWeakPointer objects can only be created by assignment from a
296 QSharedPointer.
297
298 It's important to note that QWeakPointer provides no automatic casting
299 operators to prevent mistakes from happening. Even though QWeakPointer
300 tracks a pointer, it should not be considered a pointer itself, since it
301 doesn't guarantee that the pointed object remains valid.
302
303 Therefore, to access the pointer that QWeakPointer is tracking, you must
304 first promote it to QSharedPointer and verify if the resulting object is
305 null or not. QSharedPointer guarantees that the object isn't deleted, so
306 if you obtain a non-null object, you may use the pointer. See
307 QWeakPointer::toStrongRef() for an example.
308
309 \omit
310 \section1 QWeakPointer internals
311
312 QWeakPointer shares most of its internal functionality with
313 \l{QSharedPointer#qsharedpointer-internals}{QSharedPointer}, so see that
314 class's internal documentation for more information.
315
316 QWeakPointer requires an external reference counter in order to operate.
317 Therefore, it is incompatible by design with \l QSharedData-derived
318 classes.
319
320 It has a special QObject constructor, which works by calling
321 QtSharedPointer::ExternalRefCountData::getAndRef, which retrieves the
322 d-pointer from QObjectPrivate. If one isn't set yet, that function
323 creates the d-pointer and atomically sets it.
324
325 If getAndRef needs to create a d-pointer, it sets the strongref to -1,
326 indicating that the QObject is not shared: QWeakPointer is used only to
327 determine whether the QObject has been deleted. In that case, it cannot
328 be upgraded to QSharedPointer (see the previous section).
329
330 \endomit
331
332 \sa QSharedPointer, QScopedPointer
333*/
334
335/*!
336 \class QEnableSharedFromThis
337 \inmodule QtCore
338 \brief A base class that allows obtaining a QSharedPointer for an object already managed by a shared pointer.
339 \since 5.4
340
341 You can inherit this class when you need to create a QSharedPointer
342 from any instance of a class; for instance, from within the
343 object itself. The key point is that the technique of
344 just returning QSharedPointer<T>(this) cannot be used, because
345 this winds up creating multiple distinct QSharedPointer objects
346 with separate reference counts. For this reason you must never
347 create more than one QSharedPointer from the same raw pointer.
348
349 QEnableSharedFromThis defines two member functions called
350 sharedFromThis() that return a QSharedPointer<T> and
351 QSharedPointer<const T>, depending on constness, to \c this:
352
353 \snippet code/src_corelib_tools_qsharedpointer.cpp 0
354
355 It is also possible to get a shared pointer from an object outside of
356 the class itself. This is especially useful in code that provides an
357 interface to scripts, where it is currently not possible to use shared
358 pointers. For example:
359
360 \snippet code/src_corelib_tools_qsharedpointer.cpp 1
361*/
362
363/*!
364 \fn template <class T> QSharedPointer<T>::QSharedPointer()
365
366 Creates a QSharedPointer that is null (the object is holding
367 a reference to \nullptr).
368*/
369
370/*!
371 \fn template <class T> QSharedPointer<T>::~QSharedPointer()
372
373 Destroys this QSharedPointer object. If it is the last reference to
374 the pointer stored, this will delete the pointer as well.
375*/
376
377/*!
378 \fn template <class T> template <typename X> QSharedPointer<T>::QSharedPointer(X *ptr)
379
380 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
381 becomes managed by this QSharedPointer and must not be passed to
382 another QSharedPointer object or deleted outside this object.
383
384 Since Qt 5.8, when the last reference to this QSharedPointer gets
385 destroyed, \a ptr will be deleted by calling \c X's destructor (even if \c
386 X is not the same as QSharedPointer's template parameter \c T). Previously,
387 the destructor for \c T was called.
388*/
389
390/*!
391 \fn template <class T> template <typename X, typename Deleter> QSharedPointer<T>::QSharedPointer(X *ptr, Deleter d)
392
393 Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
394 becomes managed by this QSharedPointer and must not be passed to
395 another QSharedPointer object or deleted outside this object.
396
397 The deleter parameter \a d specifies the custom deleter for this
398 object. The custom deleter is called, instead of the operator delete(),
399 when the strong reference count drops to 0. This is useful,
400 for instance, for calling \l {QObject::}{deleteLater()} on a QObject instead:
401
402 \snippet code/src_corelib_tools_qsharedpointer.cpp 2
403
404 Note that the custom deleter function will be called with a pointer to type
405 \c X, even if the QSharedPointer template parameter \c T is not the same.
406
407 It is also possible to specify a member function directly, as in:
408 \snippet code/src_corelib_tools_qsharedpointer.cpp 3
409
410 \sa clear()
411*/
412
413/*!
414 \fn template <class T> QSharedPointer<T>::QSharedPointer(std::nullptr_t)
415 \since 5.8
416
417 Creates a QSharedPointer that is null. This is equivalent to the
418 QSharedPointer default constructor.
419*/
420
421/*!
422 \fn template <class T> template <typename Deleter> QSharedPointer<T>::QSharedPointer(std::nullptr_t, Deleter d)
423 \since 5.8
424
425 Creates a QSharedPointer that is null. This is equivalent to the
426 QSharedPointer default constructor.
427
428 The deleter parameter \a d specifies the custom deleter for this
429 object. The custom deleter is called, instead of the operator
430 delete(), when the strong reference count drops to 0.
431*/
432
433/*!
434 \fn template <class T> QSharedPointer<T>::QSharedPointer(const QSharedPointer<T> &other)
435
436 Creates a QSharedPointer object that shares \a other's pointer.
437
438 If \tt T is a derived type of the template parameter of this class,
439 QSharedPointer will perform an automatic cast. Otherwise, you will
440 get a compiler error.
441*/
442
443/*!
444 \fn template <class T> QSharedPointer<T>::QSharedPointer(QSharedPointer &&other)
445
446 Move-constructs a QSharedPointer instance, making it point at the same
447 object that \a other was pointing to.
448
449 \since 5.4
450*/
451
452/*!
453 \fn template <class T> QSharedPointer<T>::operator=(QSharedPointer &&other)
454
455 Move-assigns \a other to this QSharedPointer instance.
456
457 \since 5.0
458*/
459
460/*!
461 \fn template <class T> template <class X> QSharedPointer<T>::QSharedPointer(QSharedPointer<X> &&other)
462
463 Move-constructs a QSharedPointer instance, making it point at the same
464 object that \a other was pointing to.
465
466 This constructor participates in overload resolution only if \c{X*}
467 implicitly converts to \c{T*}.
468
469 \since 5.6
470*/
471
472/*!
473 \fn template <class T> template <class X> QSharedPointer<T>::operator=(QSharedPointer<X> &&other)
474
475 Move-assigns \a other to this QSharedPointer instance.
476
477 This assignment operator participates in overload resolution only if \c{X*}
478 implicitly converts to \c{T*}.
479
480 \since 5.6
481*/
482
483/*!
484 \fn template <class T> QSharedPointer<T>::QSharedPointer(const QWeakPointer<T> &other)
485
486 Creates a QSharedPointer by promoting the weak reference \a other
487 to strong reference and sharing its pointer.
488
489 If \tt T is a derived type of the template parameter of this
490 class, QSharedPointer will perform an automatic cast. Otherwise,
491 you will get a compiler error.
492
493 \sa QWeakPointer::toStrongRef()
494*/
495
496/*!
497 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QSharedPointer<T> &other)
498
499 Makes this object share \a other's pointer. The current pointer
500 reference is discarded and, if it was the last, the pointer will
501 be deleted.
502
503 If \tt T is a derived type of the template parameter of this
504 class, QSharedPointer will perform an automatic cast. Otherwise,
505 you will get a compiler error.
506*/
507
508/*!
509 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QWeakPointer<T> &other)
510
511 Promotes \a other to a strong reference and makes this object
512 share a reference to the pointer referenced by it. The current pointer
513 reference is discarded and, if it was the last, the pointer will
514 be deleted.
515
516 If \tt T is a derived type of the template parameter of this
517 class, QSharedPointer will perform an automatic cast. Otherwise,
518 you will get a compiler error.
519*/
520
521/*!
522 \fn template <class T> void QSharedPointer<T>::swap(QSharedPointer<T> &other);
523 \since 5.3
524 \memberswap{shared pointer instance}
525*/
526
527/*!
528 \fn template <class T> T *QSharedPointer<T>::data() const
529
530 Returns the value of the pointer referenced by this object.
531
532 Note: do not delete the pointer returned by this function or pass
533 it to another function that could delete it, including creating
534 QSharedPointer or QWeakPointer objects.
535*/
536
537/*!
538 \fn template <class T> T *QSharedPointer<T>::get() const
539 \since 5.11
540
541 Same as data().
542
543 This function is provided for API compatibility with \c{std::shared_ptr}.
544*/
545
546/*!
547 \fn template <class T> T &QSharedPointer<T>::operator *() const
548
549 Provides access to the shared pointer's members.
550
551 If the contained pointer is \nullptr, behavior is undefined.
552 \sa isNull()
553*/
554
555/*!
556 \fn template <class T> T *QSharedPointer<T>::operator ->() const
557
558 Provides access to the shared pointer's members.
559
560 If the contained pointer is \nullptr, behavior is undefined.
561 \sa isNull()
562*/
563
564/*!
565 \fn template <class T> bool QSharedPointer<T>::isNull() const
566
567 Returns \c true if this object refers to \nullptr.
568*/
569
570/*!
571 \fn template <class T> QSharedPointer<T>::operator bool() const
572
573 Returns \c true if the contained pointer is not \nullptr.
574 This function is suitable for use in \tt if-constructs, like:
575
576 \snippet code/src_corelib_tools_qsharedpointer.cpp 4
577
578 \sa isNull()
579*/
580
581/*!
582 \fn template <class T> bool QSharedPointer<T>::operator !() const
583
584 Returns \c true if this object refers to \nullptr.
585 This function is suitable for use in \tt if-constructs, like:
586
587 \snippet code/src_corelib_tools_qsharedpointer.cpp 5
588
589 \sa isNull()
590*/
591
592/*!
593 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::staticCast() const
594
595 Performs a static cast from this pointer's type to \tt X and returns
596 a QSharedPointer that shares the reference. This function can be
597 used for up- and for down-casting, but is more useful for
598 up-casting.
599
600 Note: the template type \c X must have the same const and volatile
601 qualifiers as the template of this object, or the cast will
602 fail. Use constCast() if you need to drop those qualifiers.
603
604 \sa dynamicCast(), constCast(), qSharedPointerCast()
605*/
606
607/*!
608 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::dynamicCast() const
609
610 Performs a dynamic cast from this pointer's type to \tt X and
611 returns a QSharedPointer that shares the reference. If this
612 function is used to up-cast, then QSharedPointer will perform a \tt
613 dynamic_cast, which means that if the object being pointed by this
614 QSharedPointer is not of type \tt X, the returned object will be
615 null.
616
617 Note: the template type \c X must have the same const and volatile
618 qualifiers as the template of this object, or the cast will
619 fail. Use constCast() if you need to drop those qualifiers.
620
621 \sa qSharedPointerDynamicCast()
622*/
623
624/*!
625 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::constCast() const
626
627 Performs a \tt const_cast from this pointer's type to \tt X and returns
628 a QSharedPointer that shares the reference. This function can be
629 used for up- and for down-casting, but is more useful for
630 up-casting.
631
632 \sa isNull(), qSharedPointerConstCast()
633*/
634
635/*!
636 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::objectCast() const
637 \since 4.6
638
639 Performs a \l qobject_cast() from this pointer's type to \tt X and
640 returns a QSharedPointer that shares the reference. If this
641 function is used to up-cast, then QSharedPointer will perform a \tt
642 qobject_cast, which means that if the object being pointed by this
643 QSharedPointer is not of type \tt X, the returned object will be
644 null.
645
646 Note: the template type \c X must have the same const and volatile
647 qualifiers as the template of this object, or the cast will
648 fail. Use constCast() if you need to drop those qualifiers.
649
650 \sa qSharedPointerObjectCast()
651*/
652
653/*!
654 \fn template <class T> template <typename... Args> QSharedPointer<T> QSharedPointer<T>::create(Args &&... args)
655 \overload
656 \since 5.1
657
658 Creates a QSharedPointer object and allocates a new item of type \tt T. The
659 QSharedPointer internals and the object are allocated in one single memory
660 allocation, which could help reduce memory fragmentation in a long-running
661 application.
662
663 This function will attempt to call a constructor for type \tt T that can
664 accept all the arguments passed (\a args). Arguments will be perfectly-forwarded.
665*/
666
667/*!
668 \fn template <class T> QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
669
670 Returns a weak reference object that shares the pointer referenced
671 by this object.
672
673 \sa QWeakPointer::QWeakPointer()
674*/
675
676/*!
677 \fn template <class T> void QSharedPointer<T>::clear()
678
679 Clears this QSharedPointer object, dropping the reference that it
680 may have had to the pointer. If this was the last reference, then
681 the pointer itself will be deleted.
682*/
683
684/*!
685 \fn template <class T> void QSharedPointer<T>::reset()
686 \since 5.0
687
688 Same as clear(). For std::shared_ptr compatibility.
689*/
690
691/*!
692 \fn template <class T> void QSharedPointer<T>::reset(T *t)
693 \since 5.0
694
695 Resets this QSharedPointer object to point to \a t
696 instead. Equivalent to:
697 \snippet code/src_corelib_tools_qsharedpointer.cpp 6
698*/
699
700/*!
701 \fn template <class T> template <typename Deleter> void QSharedPointer<T>::reset(T *t, Deleter deleter)
702 \since 5.0
703
704 Resets this QSharedPointer object to point to \a t
705 instead, with the Deleter \a deleter. Equivalent to:
706 \snippet code/src_corelib_tools_qsharedpointer.cpp 7
707*/
708
709/*!
710 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_before(const QSharedPointer<X> &other) const noexcept
711 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_before(const QWeakPointer<X> &other) const noexcept
712 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_before(const QSharedPointer<X> &other) const noexcept
713 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_before(const QWeakPointer<X> &other) const noexcept
714 \since 6.7
715
716 Returns \c true if and only if this smart pointer precedes \a other
717 in an implementation-defined owner-based ordering. The ordering is such
718 that two smart pointers are considered equivalent if they are both
719 empty or if they both own the same object (even if their apparent type
720 and pointer are different).
721
722 \sa owner_equal
723*/
724
725/*!
726 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_equal(const QSharedPointer<X> &other) const noexcept
727 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_equal(const QWeakPointer<X> &other) const noexcept
728 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_equal(const QSharedPointer<X> &other) const noexcept
729 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_equal(const QWeakPointer<X> &other) const noexcept
730
731 \since 6.7
732
733 Returns \c true if and only if this smart pointer and \a other
734 share ownership.
735
736 \sa owner_before, owner_hash
737*/
738
739/*!
740 \fn template <class T> size_t QSharedPointer<T>::owner_hash() const noexcept
741 \fn template <class T> size_t QWeakPointer<T>::owner_hash() const noexcept
742
743 \since 6.7
744
745 Returns a owner-based hash value for this smart pointer object.
746 Smart pointers that compare equal (as per \c{owner_equal}) will
747 have an identical owner-based hash.
748
749 \sa owner_equal
750*/
751
752/*!
753 \fn template <class T> QWeakPointer<T>::QWeakPointer()
754
755 Creates a QWeakPointer that points to nothing.
756*/
757
758/*!
759 \fn template <class T> QWeakPointer<T>::~QWeakPointer()
760
761 Destroys this QWeakPointer object. The pointer referenced
762 by this object will not be deleted.
763*/
764
765/*!
766 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QWeakPointer<T> &other)
767
768 Creates a QWeakPointer that holds a weak reference to the
769 pointer referenced by \a other.
770
771 If \tt T is a derived type of the template parameter of this
772 class, QWeakPointer will perform an automatic cast. Otherwise,
773 you will get a compiler error.
774*/
775
776/*!
777 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QSharedPointer<T> &other)
778
779 Creates a QWeakPointer that holds a weak reference to the
780 pointer referenced by \a other.
781
782 If \tt T is a derived type of the template parameter of this
783 class, QWeakPointer will perform an automatic cast. Otherwise,
784 you will get a compiler error.
785*/
786
787/*!
788 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QObject *other)
789 \since 4.6
790 \deprecated
791
792 Creates a QWeakPointer that holds a weak reference directly to the
793 QObject \a other. This constructor is only available if the template type
794 \tt T is QObject or derives from it (otherwise a compilation error will
795 result).
796
797 You can use this constructor with any QObject, even if they were not
798 created with \l QSharedPointer.
799
800 Note that QWeakPointers created this way on arbitrary QObjects usually
801 cannot be promoted to QSharedPointer.
802
803 \sa QSharedPointer, QPointer
804*/
805
806/*!
807 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QObject *other)
808 \since 4.6
809 \deprecated
810
811 Makes this QWeakPointer hold a weak reference directly to the QObject
812 \a other. This function is only available if the template type \tt T is
813 QObject or derives from it.
814
815 \sa QPointer
816*/
817
818/*!
819 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QWeakPointer<T> &other)
820
821 Makes this object share \a other's pointer. The current pointer
822 reference is discarded but is not deleted.
823
824 If \tt T is a derived type of the template parameter of this
825 class, QWeakPointer will perform an automatic cast. Otherwise,
826 you will get a compiler error.
827*/
828
829/*!
830 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QSharedPointer<T> &other)
831
832 Makes this object share \a other's pointer. The current pointer
833 reference is discarded but is not deleted.
834
835 If \tt T is a derived type of the template parameter of this
836 class, QWeakPointer will perform an automatic cast. Otherwise,
837 you will get a compiler error.
838*/
839
840/*!
841 \fn template <class T> void QWeakPointer<T>::swap(QWeakPointer<T> &other)
842 \since 5.4
843 \memberswap{weak pointer instance}
844*/
845
846/*!
847 \fn template <class T> bool QWeakPointer<T>::isNull() const
848
849 Returns \c true if this object refers to \nullptr.
850
851 Note that, due to the nature of weak references, the pointer that
852 QWeakPointer references can become \nullptr at any moment, so
853 the value returned from this function can change from false to
854 true from one call to the next.
855*/
856
857/*!
858 \fn template <class T> QWeakPointer<T>::operator bool() const
859
860 Returns \c true if the contained pointer is not \nullptr.
861 This function is suitable for use in \tt if-constructs, like:
862
863 \snippet code/src_corelib_tools_qsharedpointer.cpp 8
864
865 Note that, due to the nature of weak references, the pointer that
866 QWeakPointer references can become \nullptr at any moment, so
867 the value returned from this function can change from true to
868 false from one call to the next.
869
870 \sa isNull()
871*/
872
873/*!
874 \fn template <class T> bool QWeakPointer<T>::operator !() const
875
876 Returns \c true if this object refers to \nullptr.
877 This function is suitable for use in \tt if-constructs, like:
878
879 \snippet code/src_corelib_tools_qsharedpointer.cpp 9
880
881 Note that, due to the nature of weak references, the pointer that
882 QWeakPointer references can become \nullptr at any moment, so
883 the value returned from this function can change from false to
884 true from one call to the next.
885
886 \sa isNull()
887*/
888
889/*!
890 \fn template <class T> T *QWeakPointer<T>::data() const
891 \since 4.6
892 \deprecated Use toStrongRef() instead, and data() on the returned QSharedPointer.
893
894 Returns the value of the pointer being tracked by this QWeakPointer,
895 \b without ensuring that it cannot get deleted. To have that guarantee,
896 use toStrongRef(), which returns a QSharedPointer object. If this
897 function can determine that the pointer has already been deleted, it
898 returns \nullptr.
899
900 It is ok to obtain the value of the pointer and using that value itself,
901 like for example in debugging statements:
902
903 \snippet code/src_corelib_tools_qsharedpointer.cpp 10
904
905 However, dereferencing the pointer is only allowed if you can guarantee
906 by external means that the pointer does not get deleted. For example,
907 if you can be certain that no other thread can delete it, nor the
908 functions that you may call.
909
910 If that is the case, then the following code is valid:
911
912 \snippet code/src_corelib_tools_qsharedpointer.cpp 11
913
914 Use this function with care.
915
916 \sa isNull(), toStrongRef()
917*/
918
919/*!
920 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::toStrongRef() const
921
922 Promotes this weak reference to a strong one and returns a
923 QSharedPointer object holding that reference. When promoting to
924 QSharedPointer, this function verifies if the object has been deleted
925 already or not. If it hasn't, this function increases the reference
926 count to the shared object, thus ensuring that it will not get
927 deleted.
928
929 Since this function can fail to obtain a valid strong reference to the
930 shared object, you should always verify if the conversion succeeded,
931 by calling QSharedPointer::isNull() on the returned object.
932
933 For example, the following code promotes a QWeakPointer that was held
934 to a strong reference and, if it succeeded, it prints the value of the
935 integer that was held:
936
937 \snippet code/src_corelib_tools_qsharedpointer.cpp 12
938
939 \sa QSharedPointer::QSharedPointer()
940*/
941
942/*!
943 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::lock() const
944 \since 5.4
945
946 Same as toStrongRef().
947
948 This function is provided for API compatibility with std::weak_ptr.
949*/
950
951/*!
952 \fn template <class T> void QWeakPointer<T>::clear()
953
954 Clears this QWeakPointer object, dropping the reference that it
955 may have had to the pointer.
956*/
957
958/*!
959 \fn template <class T> QSharedPointer<T> QEnableSharedFromThis<T>::sharedFromThis()
960 \since 5.4
961
962 If \c this (that is, the subclass instance invoking this method) is being
963 managed by a QSharedPointer, returns a shared pointer instance pointing to
964 \c this; otherwise returns a null QSharedPointer.
965*/
966
967/*!
968 \fn template <class T> QSharedPointer<const T> QEnableSharedFromThis<T>::sharedFromThis() const
969 \overload
970 \since 5.4
971
972 Const overload of sharedFromThis().
973*/
974
975/*!
976 \fn template <class T> qHash(const QSharedPointer<T> &key, size_t seed)
977 \qhashold{QSharedPointer}
978 \since 5.0
979*/
980
981/*!
982 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
983 \relates QSharedPointer
984
985 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
986
987 If \a ptr2's template parameter is different from \a ptr1's,
988 QSharedPointer will attempt to perform an automatic \tt static_cast
989 to ensure that the pointers being compared are equal. If \a ptr2's
990 template parameter is not a base or a derived type from
991 \a ptr1's, you will get a compiler error.
992*/
993
994/*!
995 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
996 \relates QSharedPointer
997
998 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
999
1000 If \a ptr2's template parameter is different from \a ptr1's,
1001 QSharedPointer will attempt to perform an automatic \tt static_cast
1002 to ensure that the pointers being compared are equal. If \a ptr2's
1003 template parameter is not a base or a derived type from
1004 \a ptr1's, you will get a compiler error.
1005*/
1006
1007/*!
1008 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
1009 \relates QSharedPointer
1010
1011 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1012
1013 If \a ptr2's type is different from \a ptr1's,
1014 QSharedPointer will attempt to perform an automatic \tt static_cast
1015 to ensure that the pointers being compared are equal. If \a ptr2's
1016 type is not a base or a derived type from this
1017 \a ptr1's, you will get a compiler error.
1018*/
1019
1020/*!
1021 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
1022 \relates QSharedPointer
1023
1024 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1025
1026 If \a ptr2's type is different from \a ptr1's,
1027 QSharedPointer will attempt to perform an automatic \tt static_cast
1028 to ensure that the pointers being compared are equal. If \a ptr2's
1029 type is not a base or a derived type from this
1030 \a ptr1's, you will get a compiler error.
1031*/
1032
1033/*!
1034 \fn template<class T, class X> bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
1035 \relates QSharedPointer
1036
1037 Returns \c true if the pointer \a ptr1 is the
1038 same pointer as that referenced by \a ptr2.
1039
1040 If \a ptr2's template parameter is different from \a ptr1's type,
1041 QSharedPointer will attempt to perform an automatic \tt static_cast
1042 to ensure that the pointers being compared are equal. If \a ptr2's
1043 template parameter is not a base or a derived type from
1044 \a ptr1's type, you will get a compiler error.
1045*/
1046
1047/*!
1048 \fn template<class T, class X> bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
1049 \relates QSharedPointer
1050
1051 Returns \c true if the pointer \a ptr1 is not the
1052 same pointer as that referenced by \a ptr2.
1053
1054 If \a ptr2's template parameter is different from \a ptr1's type,
1055 QSharedPointer will attempt to perform an automatic \tt static_cast
1056 to ensure that the pointers being compared are equal. If \a ptr2's
1057 template parameter is not a base or a derived type from
1058 \a ptr1's type, you will get a compiler error.
1059*/
1060
1061/*!
1062 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1063 \relates QWeakPointer
1064
1065 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1066
1067 If \a ptr2's template parameter is different from \a ptr1's,
1068 QSharedPointer will attempt to perform an automatic \tt static_cast
1069 to ensure that the pointers being compared are equal. If \a ptr2's
1070 template parameter is not a base or a derived type from
1071 \a ptr1's, you will get a compiler error.
1072*/
1073
1074/*!
1075 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1076 \relates QWeakPointer
1077
1078 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1079
1080 If \a ptr2's template parameter is different from \a ptr1's,
1081 QSharedPointer will attempt to perform an automatic \tt static_cast
1082 to ensure that the pointers being compared are equal. If \a ptr2's
1083 template parameter is not a base or a derived type from
1084 \a ptr1's, you will get a compiler error.
1085*/
1086
1087/*!
1088 \fn template<class T, class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1089 \relates QWeakPointer
1090
1091 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1092
1093 If \a ptr2's template parameter is different from \a ptr1's,
1094 QSharedPointer will attempt to perform an automatic \tt static_cast
1095 to ensure that the pointers being compared are equal. If \a ptr2's
1096 template parameter is not a base or a derived type from
1097 \a ptr1's, you will get a compiler error.
1098*/
1099
1100/*!
1101 \fn template <class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t)
1102 \relates QSharedPointer
1103 \since 5.8
1104
1105 Returns \c true if \a lhs refers to \nullptr.
1106
1107 \sa QSharedPointer::isNull()
1108*/
1109
1110/*!
1111 \fn template <class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs)
1112 \relates QSharedPointer
1113 \since 5.8
1114
1115 Returns \c true if \a rhs refers to \nullptr.
1116
1117 \sa QSharedPointer::isNull()
1118*/
1119
1120/*!
1121 \fn template <class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t)
1122 \relates QSharedPointer
1123 \since 5.8
1124
1125 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1126
1127 \sa QSharedPointer::isNull()
1128*/
1129
1130/*!
1131 \fn template <class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs)
1132 \relates QSharedPointer
1133 \since 5.8
1134
1135 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1136
1137 \sa QSharedPointer::isNull()
1138*/
1139
1140/*!
1141 \fn template <class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t)
1142 \relates QWeakPointer
1143 \since 5.8
1144
1145 Returns \c true if \a lhs refers to \nullptr.
1146
1147 \sa QWeakPointer::isNull()
1148*/
1149
1150/*!
1151 \fn template <class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs)
1152 \relates QWeakPointer
1153 \since 5.8
1154
1155 Returns \c true if \a rhs refers to \nullptr.
1156
1157 \sa QWeakPointer::isNull()
1158*/
1159
1160/*!
1161 \fn template <class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t)
1162 \relates QWeakPointer
1163 \since 5.8
1164
1165 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1166
1167 \sa QWeakPointer::isNull()
1168*/
1169
1170/*!
1171 \fn template <class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs)
1172 \relates QWeakPointer
1173 \since 5.8
1174
1175 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1176
1177 \sa QWeakPointer::isNull()
1178*/
1179
1180/*!
1181 \fn template<class T, class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1182 \relates QWeakPointer
1183
1184 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1185
1186 If \a ptr2's template parameter is different from \a ptr1's,
1187 QSharedPointer will attempt to perform an automatic \tt static_cast
1188 to ensure that the pointers being compared are equal. If \a ptr2's
1189 template parameter is not a base or a derived type from
1190 \a ptr1's, you will get a compiler error.
1191*/
1192
1193/*!
1194 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
1195 \relates QSharedPointer
1196
1197 Returns a shared pointer to the pointer held by \a other, cast to
1198 type \tt X. The types \tt T and \tt X must belong to one
1199 hierarchy for the \tt static_cast to succeed.
1200
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.
1204
1205 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1206*/
1207
1208/*!
1209 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
1210 \relates QSharedPointer
1211 \relates QWeakPointer
1212
1213 Returns a shared pointer to the pointer held by \a other, cast to
1214 type \tt X. The types \tt T and \tt X must belong to one
1215 hierarchy for the \tt static_cast to succeed.
1216
1217 The \a other object is converted first to a strong reference. If
1218 that conversion fails (because the object it's pointing to has
1219 already been deleted), this function returns a null
1220 QSharedPointer.
1221
1222 Note that \tt X must have the same cv-qualifiers (\tt const and
1223 \tt volatile) that \tt T has, or the code will fail to
1224 compile. Use qSharedPointerConstCast to cast away the constness.
1225
1226 \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1227*/
1228
1229/*!
1230 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1231 \relates QSharedPointer
1232
1233 Returns a shared pointer to the pointer held by \a src, using a
1234 dynamic cast to type \tt X to obtain an internal pointer of the
1235 appropriate type. If the \tt dynamic_cast fails, the object
1236 returned will be null.
1237
1238 Note that \tt X must have the same cv-qualifiers (\tt const and
1239 \tt volatile) that \tt T has, or the code will fail to
1240 compile. Use qSharedPointerConstCast to cast away the constness.
1241
1242 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1243*/
1244
1245/*!
1246 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
1247 \relates QSharedPointer
1248 \relates QWeakPointer
1249
1250 Returns a shared pointer to the pointer held by \a src, using a
1251 dynamic cast to type \tt X to obtain an internal pointer of the
1252 appropriate type. If the \tt dynamic_cast fails, the object
1253 returned will be null.
1254
1255 The \a src object is converted first to a strong reference. If
1256 that conversion fails (because the object it's pointing to has
1257 already been deleted), this function also returns a null
1258 QSharedPointer.
1259
1260 Note that \tt X must have the same cv-qualifiers (\tt const and
1261 \tt volatile) that \tt T has, or the code will fail to
1262 compile. Use qSharedPointerConstCast to cast away the constness.
1263
1264 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1265*/
1266
1267/*!
1268 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
1269 \relates QSharedPointer
1270
1271 Returns a shared pointer to the pointer held by \a src, cast to
1272 type \tt X. The types \tt T and \tt X must belong to one
1273 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1274 volatile differences between \tt T and \tt X are ignored.
1275
1276 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1277*/
1278
1279/*!
1280 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
1281 \relates QSharedPointer
1282 \relates QWeakPointer
1283
1284 Returns a shared pointer to the pointer held by \a src, cast to
1285 type \tt X. The types \tt T and \tt X must belong to one
1286 hierarchy for the \tt const_cast to succeed. The \tt const and
1287 \tt volatile differences between \tt T and \tt X are ignored.
1288
1289 The \a src object is converted first to a strong reference. If
1290 that conversion fails (because the object it's pointing to has
1291 already been deleted), this function returns a null
1292 QSharedPointer.
1293
1294 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
1295*/
1296
1297/*!
1298 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
1299 \relates QSharedPointer
1300 \since 4.6
1301
1302 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1303
1304 Returns a shared pointer to the pointer held by \a src, using a
1305 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1306 appropriate type. If the \tt qobject_cast fails, the object
1307 returned will be null.
1308
1309 Note that \tt X must have the same cv-qualifiers (\tt const and
1310 \tt volatile) that \tt T has, or the code will fail to
1311 compile. Use qSharedPointerConstCast to cast away the constness.
1312
1313 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1314*/
1315
1316/*!
1317 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
1318 \relates QSharedPointer
1319 \since 5.14
1320
1321 Returns a shared pointer to the pointer held by \a src, using a
1322 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1323 appropriate type. If the \tt qobject_cast fails, the object
1324 returned will be null.
1325
1326 Note that \tt X must have the same cv-qualifiers (\tt const and
1327 \tt volatile) that \tt T has, or the code will fail to
1328 compile. Use const_pointer_cast to cast away the constness.
1329*/
1330
1331/*!
1332 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
1333 \relates QSharedPointer
1334 \since 5.14
1335
1336 Returns a shared pointer to the pointer held by \a src.
1337
1338 Same as qSharedPointerObjectCast(). This function is provided for STL
1339 compatibility.
1340*/
1341
1342/*!
1343 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
1344 \relates QSharedPointer
1345 \since 5.14
1346
1347 Returns a shared pointer to the pointer held by \a src, using a
1348 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1349 appropriate type.
1350
1351 If the \tt qobject_cast succeeds, the function will return a valid shared
1352 pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
1353 object returned will be null, and \a src will not be modified.
1354
1355 Note that \tt X must have the same cv-qualifiers (\tt const and
1356 \tt volatile) that \tt T has, or the code will fail to
1357 compile. Use const_pointer_cast to cast away the constness.
1358*/
1359
1360/*!
1361 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
1362 \relates QSharedPointer
1363 \since 5.14
1364
1365 Same as qSharedPointerObjectCast(). This function is provided for STL
1366 compatibility.
1367*/
1368
1369/*!
1370 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
1371 \relates QSharedPointer
1372 \relates QWeakPointer
1373 \since 4.6
1374
1375 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1376
1377 Returns a shared pointer to the pointer held by \a src, using a
1378 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1379 appropriate type. If the \tt qobject_cast fails, the object
1380 returned will be null.
1381
1382 The \a src object is converted first to a strong reference. If
1383 that conversion fails (because the object it's pointing to has
1384 already been deleted), this function also returns a null
1385 QSharedPointer.
1386
1387 Note that \tt X must have the same cv-qualifiers (\tt const and
1388 \tt volatile) that \tt T has, or the code will fail to
1389 compile. Use qSharedPointerConstCast to cast away the constness.
1390
1391 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1392*/
1393
1394
1395/*!
1396 \fn template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
1397 \relates QWeakPointer
1398
1399 Returns a weak pointer to the pointer held by \a src, cast to
1400 type \tt X. The types \tt T and \tt X must belong to one
1401 hierarchy for the \tt static_cast to succeed.
1402
1403 Note that \tt X must have the same cv-qualifiers (\tt const and
1404 \tt volatile) that \tt T has, or the code will fail to
1405 compile. Use qSharedPointerConstCast to cast away the constness.
1406*/
1407
1408#include <qset.h>
1409#include <qmutex.h>
1410
1411#if !defined(QT_NO_QOBJECT)
1412#include "private/qobject_p.h"
1413
1414QT_BEGIN_NAMESPACE
1415
1416QT6_ONLY(
1417/*!
1418 \internal
1419 This function is called for a just-created QObject \a obj, to enable
1420 the use of QSharedPointer and QWeakPointer in the future.
1421 */
1422void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1423{}
1424)
1425
1426QT6_ONLY(
1427/*!
1428 \internal
1429 This function is called when a QSharedPointer is created from a QWeakPointer
1430
1431 We check that the QWeakPointer was really created from a QSharedPointer, and
1432 not from a QObject.
1433*/
1434void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1435{
1436 if (strongref.loadRelaxed() < 0)
1437 qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1438}
1439)
1440
1441QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1442{
1443 Q_ASSERT(obj);
1444 QObjectPrivate *d = QObjectPrivate::get(o: const_cast<QObject *>(obj));
1445 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1446
1447 ExternalRefCountData *that = d->sharedRefcount.loadRelaxed();
1448 if (that) {
1449 that->weakref.ref();
1450 return that;
1451 }
1452
1453 // we can create the refcount data because it doesn't exist
1454 ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
1455 x->strongref.storeRelaxed(newValue: -1);
1456 x->weakref.storeRelaxed(newValue: 2); // the QWeakPointer that called us plus the QObject itself
1457
1458 ExternalRefCountData *ret;
1459 if (d->sharedRefcount.testAndSetOrdered(expectedValue: nullptr, newValue: x, currentValue&: ret)) { // ought to be release+acquire; this is acq_rel+acquire
1460 ret = x;
1461 } else {
1462 // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
1463 // only execute this if Q_ASSERTs are enabled
1464 Q_ASSERT((x->weakref.storeRelaxed(0), true));
1465 ::delete x;
1466 ret->weakref.ref();
1467 }
1468 return ret;
1469}
1470
1471/**
1472 \internal
1473 Returns a QSharedPointer<QObject> if the variant contains
1474 a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1475*/
1476QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
1477{
1478 Q_ASSERT(variant.metaType().flags() & QMetaType::SharedPointerToQObject);
1479 return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
1480}
1481
1482/**
1483 \internal
1484 Returns a QWeakPointer<QObject> if the variant contains
1485 a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1486*/
1487QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
1488{
1489 Q_ASSERT(variant.metaType().flags() & QMetaType::WeakPointerToQObject ||
1490 variant.metaType().flags() & QMetaType::TrackingPointerToQObject);
1491 return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
1492}
1493
1494QT_END_NAMESPACE
1495
1496#endif
1497
1498
1499
1500//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1501# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1502# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1503# define BACKTRACE_SUPPORTED
1504# elif defined(Q_OS_DARWIN)
1505# define BACKTRACE_SUPPORTED
1506# endif
1507# endif
1508
1509# if defined(BACKTRACE_SUPPORTED)
1510# include <sys/types.h>
1511# include <execinfo.h>
1512# include <stdio.h>
1513# include <unistd.h>
1514# include <sys/wait.h>
1515
1516QT_BEGIN_NAMESPACE
1517
1518static inline QByteArray saveBacktrace() __attribute__((always_inline));
1519static inline QByteArray saveBacktrace()
1520{
1521 static const int maxFrames = 32;
1522
1523 QByteArray stacktrace;
1524 stacktrace.resize(sizeof(void*) * maxFrames);
1525 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1526 stacktrace.resize(sizeof(void*) * stack_size);
1527
1528 return stacktrace;
1529}
1530
1531static void printBacktrace(QByteArray stacktrace)
1532{
1533 void *const *stack = (void *const *)stacktrace.constData();
1534 int stack_size = stacktrace.size() / sizeof(void*);
1535 char **stack_symbols = backtrace_symbols(stack, stack_size);
1536
1537 int filter[2];
1538 pid_t child = -1;
1539 if (pipe(filter) != -1)
1540 child = fork();
1541 if (child == 0) {
1542 // child process
1543 dup2(fileno(stderr), fileno(stdout));
1544 dup2(filter[0], fileno(stdin));
1545 close(filter[0]);
1546 close(filter[1]);
1547 execlp("c++filt", "c++filt", "-n", NULL);
1548
1549 // execlp failed
1550 execl("/bin/cat", "/bin/cat", NULL);
1551 _exit(127);
1552 }
1553
1554 // parent process
1555 close(filter[0]);
1556 FILE *output;
1557 if (child == -1) {
1558 // failed forking
1559 close(filter[1]);
1560 output = stderr;
1561 } else {
1562 output = fdopen(filter[1], "w");
1563 }
1564
1565 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1566 for (int i = 0; i < stack_size; ++i) {
1567 if (strlen(stack_symbols[i]))
1568 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1569 else
1570 fprintf(output, "#%-2d %p\n", i, stack[i]);
1571 }
1572
1573 if (child != -1) {
1574 fclose(output);
1575 waitpid(child, 0, 0);
1576 }
1577}
1578
1579QT_END_NAMESPACE
1580
1581# endif // BACKTRACE_SUPPORTED
1582
1583namespace {
1584 QT_USE_NAMESPACE
1585 struct Data {
1586 const volatile void *pointer;
1587# ifdef BACKTRACE_SUPPORTED
1588 QByteArray backtrace;
1589# endif
1590 };
1591
1592 class KnownPointers
1593 {
1594 public:
1595 QMutex mutex;
1596 QHash<const void *, Data> dPointers;
1597 QHash<const volatile void *, const void *> dataPointers;
1598 };
1599}
1600
1601Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1602
1603QT_BEGIN_NAMESPACE
1604
1605namespace QtSharedPointer {
1606 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1607}
1608
1609/*!
1610 \internal
1611*/
1612void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1613{
1614 KnownPointers *const kp = knownPointers();
1615 if (!kp)
1616 return; // end-game: the application is being destroyed already
1617
1618 if (!ptr) {
1619 // nullptr is allowed to be tracked by more than one QSharedPointer, so we
1620 // need something else to put in our tracking structures
1621 ptr = d_ptr;
1622 }
1623
1624 QMutexLocker lock(&kp->mutex);
1625 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1626
1627 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1628
1629 const void *other_d_ptr = kp->dataPointers.value(key: ptr, defaultValue: nullptr);
1630 if (Q_UNLIKELY(other_d_ptr)) {
1631# ifdef BACKTRACE_SUPPORTED
1632 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1633# endif
1634 qFatal(msg: "QSharedPointer: internal self-check failed: pointer %p was already tracked "
1635 "by another QSharedPointer object %p", ptr, other_d_ptr);
1636 }
1637
1638 Data data;
1639 data.pointer = ptr;
1640# ifdef BACKTRACE_SUPPORTED
1641 data.backtrace = saveBacktrace();
1642# endif
1643
1644 kp->dPointers.insert(key: d_ptr, value: data);
1645 kp->dataPointers.insert(key: ptr, value: d_ptr);
1646 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1647}
1648
1649/*!
1650 \internal
1651*/
1652void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1653{
1654 KnownPointers *const kp = knownPointers();
1655 if (!kp)
1656 return; // end-game: the application is being destroyed already
1657
1658 QMutexLocker lock(&kp->mutex);
1659
1660 const auto it = kp->dPointers.constFind(key: d_ptr);
1661 if (Q_UNLIKELY(it == kp->dPointers.cend())) {
1662 qFatal(msg: "QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1663 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1664 "in your code.", d_ptr);
1665 }
1666
1667 const auto it2 = kp->dataPointers.constFind(key: it->pointer);
1668 Q_ASSERT(it2 != kp->dataPointers.cend());
1669
1670 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1671
1672 // remove entries
1673 kp->dataPointers.erase(it: it2);
1674 kp->dPointers.erase(it);
1675 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1676}
1677
1678/*!
1679 \internal
1680 Called by the QSharedPointer autotest
1681*/
1682void QtSharedPointer::internalSafetyCheckCleanCheck()
1683{
1684# ifdef QT_BUILD_INTERNAL
1685 KnownPointers *const kp = knownPointers();
1686 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1687
1688 if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
1689 qFatal(msg: "Internal consistency error: the number of pointers is not equal!");
1690
1691 if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
1692 qFatal(msg: "Pointer cleaning failed: %d entries remaining", int(kp->dPointers.size()));
1693# endif
1694}
1695
1696QT_END_NAMESPACE
1697

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/corelib/tools/qsharedpointer.cpp