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