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(), qSharedPointerStaticCast()
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(), qSharedPointerStaticCast()
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> qSharedPointerStaticCast(const QSharedPointer<T> &other)
1228 \since 6.12
1229 \relates QSharedPointer
1230
1231 Returns a shared pointer to the pointer held by \a other, cast to
1232 type \tt X. The types \tt T and \tt X must belong to one
1233 hierarchy for the \tt static_cast to succeed.
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::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1240*/
1241
1242/*!
1243 \fn template <class X, class T> QSharedPointer<X> qSharedPointerStaticCast(QSharedPointer<T> &&other)
1244 \relates QSharedPointer
1245 \since 6.12
1246 \overload qSharedPointerStaticCast(const QSharedPointer<T> &other)
1247
1248 \include qsharedpointer.cpp {cast-overload-for-arg} {other}
1249
1250 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1251*/
1252
1253/*!
1254 \fn template <class X, class T> QSharedPointer<X> qSharedPointerStaticCast(const QWeakPointer<T> &other)
1255 \since 6.12
1256 \relates QSharedPointer
1257 \relates QWeakPointer
1258
1259 Returns a shared pointer to the pointer held by \a other, cast to
1260 type \tt X. The types \tt T and \tt X must belong to one
1261 hierarchy for the \tt static_cast to succeed.
1262
1263 The \a other 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 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(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1273*/
1274
1275/*!
1276 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1277 \relates QSharedPointer
1278
1279 Returns a shared pointer to the pointer held by \a src, using a
1280 dynamic cast to type \tt X to obtain an internal pointer of the
1281 appropriate type. If the \tt dynamic_cast fails, the object
1282 returned will be null.
1283
1284 Note that \tt X must have the same cv-qualifiers (\tt const and
1285 \tt volatile) that \tt T has, or the code will fail to
1286 compile. Use qSharedPointerConstCast to cast away the constness.
1287
1288 \sa QSharedPointer::dynamicCast(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1289*/
1290
1291/*!
1292 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(QSharedPointer<T> &&src)
1293 \relates QSharedPointer
1294 \since 6.9
1295 \overload qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1296
1297 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1298
1299 \sa QSharedPointer::dynamicCast(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1300*/
1301
1302/*!
1303 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
1304 \relates QSharedPointer
1305 \relates QWeakPointer
1306
1307 Returns a shared pointer to the pointer held by \a src, using a
1308 dynamic cast to type \tt X to obtain an internal pointer of the
1309 appropriate type. If the \tt dynamic_cast fails, the object
1310 returned will be null.
1311
1312 The \a src object is converted first to a strong reference. If
1313 that conversion fails (because the object it's pointing to has
1314 already been deleted), this function also returns a null
1315 QSharedPointer.
1316
1317 Note that \tt X must have the same cv-qualifiers (\tt const and
1318 \tt volatile) that \tt T has, or the code will fail to
1319 compile. Use qSharedPointerConstCast to cast away the constness.
1320
1321 \sa QWeakPointer::toStrongRef(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1322*/
1323
1324/*!
1325 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
1326 \relates QSharedPointer
1327
1328 Returns a shared pointer to the pointer held by \a src, cast to
1329 type \tt X. The types \tt T and \tt X must belong to one
1330 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1331 volatile differences between \tt T and \tt X are ignored.
1332
1333 \sa QSharedPointer::constCast(), qSharedPointerStaticCast(), qSharedPointerDynamicCast()
1334*/
1335
1336/*!
1337 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(QSharedPointer<T> &&src)
1338 \relates QSharedPointer
1339 \since 6.9
1340 \overload qSharedPointerConstCast(const QSharedPointer<T> &src)
1341
1342 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1343
1344 \sa QSharedPointer::constCast(), qSharedPointerStaticCast(), qSharedPointerDynamicCast()
1345*/
1346
1347/*!
1348 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
1349 \relates QSharedPointer
1350 \relates QWeakPointer
1351
1352 Returns a shared pointer to the pointer held by \a src, cast to
1353 type \tt X. The types \tt T and \tt X must belong to one
1354 hierarchy for the \tt const_cast to succeed. The \tt const and
1355 \tt volatile differences between \tt T and \tt X are ignored.
1356
1357 The \a src object is converted first to a strong reference. If
1358 that conversion fails (because the object it's pointing to has
1359 already been deleted), this function returns a null
1360 QSharedPointer.
1361
1362 \sa QWeakPointer::toStrongRef(), qSharedPointerStaticCast(), qSharedPointerDynamicCast()
1363*/
1364
1365/*!
1366 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
1367 \relates QSharedPointer
1368 \since 4.6
1369
1370 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1371
1372 Returns a shared pointer to the pointer held by \a src, using a
1373 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1374 appropriate type. If the \tt qobject_cast fails, the object
1375 returned will be null.
1376
1377 Note that \tt X must have the same cv-qualifiers (\tt const and
1378 \tt volatile) that \tt T has, or the code will fail to
1379 compile. Use qSharedPointerConstCast to cast away the constness.
1380
1381 \sa QSharedPointer::objectCast(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1382*/
1383
1384/*!
1385 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(QSharedPointer<T> &&src)
1386 \relates QSharedPointer
1387 \since 6.9
1388 \overload qSharedPointerObjectCast(const QSharedPointer<T> &src)
1389
1390 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1391
1392 \sa QSharedPointer::objectCast(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1393*/
1394
1395/*!
1396 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
1397 \relates QSharedPointer
1398 \since 5.14
1399
1400 Returns a shared pointer to the pointer held by \a src, using a
1401 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1402 appropriate type. If the \tt qobject_cast fails, the object
1403 returned will be null.
1404
1405 Note that \tt X must have the same cv-qualifiers (\tt const and
1406 \tt volatile) that \tt T has, or the code will fail to
1407 compile. Use const_pointer_cast to cast away the constness.
1408*/
1409
1410/*!
1411 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
1412 \relates QSharedPointer
1413 \since 5.14
1414
1415 Returns a shared pointer to the pointer held by \a src.
1416
1417 Same as qSharedPointerObjectCast(). This function is provided for STL
1418 compatibility.
1419*/
1420
1421/*!
1422 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
1423 \relates QSharedPointer
1424 \since 5.14
1425
1426 Returns a shared pointer to the pointer held by \a src, using a
1427 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1428 appropriate type.
1429
1430 If the \tt qobject_cast succeeds, the function will return a valid shared
1431 pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
1432 object returned will be null, and \a src will not be modified.
1433
1434 Note that \tt X must have the same cv-qualifiers (\tt const and
1435 \tt volatile) that \tt T has, or the code will fail to
1436 compile. Use const_pointer_cast to cast away the constness.
1437*/
1438
1439/*!
1440 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
1441 \relates QSharedPointer
1442 \since 5.14
1443
1444 Same as qSharedPointerObjectCast(). This function is provided for STL
1445 compatibility.
1446*/
1447
1448/*!
1449 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
1450 \relates QSharedPointer
1451 \relates QWeakPointer
1452 \since 4.6
1453
1454 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1455
1456 Returns a shared pointer to the pointer held by \a src, using a
1457 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1458 appropriate type. If the \tt qobject_cast fails, the object
1459 returned will be null.
1460
1461 The \a src object is converted first to a strong reference. If
1462 that conversion fails (because the object it's pointing to has
1463 already been deleted), this function also returns a null
1464 QSharedPointer.
1465
1466 Note that \tt X must have the same cv-qualifiers (\tt const and
1467 \tt volatile) that \tt T has, or the code will fail to
1468 compile. Use qSharedPointerConstCast to cast away the constness.
1469
1470 \sa QWeakPointer::toStrongRef(), qSharedPointerStaticCast(), qSharedPointerConstCast()
1471*/
1472
1473
1474/*!
1475 \fn template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
1476 \relates QWeakPointer
1477
1478 Returns a weak pointer to the pointer held by \a src, cast to
1479 type \tt X. The types \tt T and \tt X must belong to one
1480 hierarchy for the \tt static_cast to succeed.
1481
1482 Note that \tt X must have the same cv-qualifiers (\tt const and
1483 \tt volatile) that \tt T has, or the code will fail to
1484 compile. Use qSharedPointerConstCast to cast away the constness.
1485*/
1486
1487#include <qset.h>
1488#include <qmutex.h>
1489
1490#if !defined(QT_NO_QOBJECT)
1491#include "private/qobject_p.h"
1492
1494
1495QT6_ONLY(
1496/*!
1497 \internal
1498 This function is called for a just-created QObject \a obj, to enable
1499 the use of QSharedPointer and QWeakPointer in the future.
1500 */
1501void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1502{}
1503)
1504
1505QT6_ONLY(
1506/*!
1507 \internal
1508 This function is called when a QSharedPointer is created from a QWeakPointer
1509
1510 We check that the QWeakPointer was really created from a QSharedPointer, and
1511 not from a QObject.
1512*/
1513void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1514{
1515 if (strongref.loadRelaxed() < 0)
1516 qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1517}
1518)
1519
1520QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1521{
1522 Q_ASSERT(obj);
1523 QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
1524 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1525
1526 ExternalRefCountData *that = d->sharedRefcount.loadAcquire();
1527 if (that) {
1528 that->weakref.ref();
1529 return that;
1530 }
1531
1532 // we can create the refcount data because it doesn't exist
1533 ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
1534 x->strongref.storeRelaxed(-1);
1535 x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
1536 x->destroyer = nullptr;
1537
1538 ExternalRefCountData *ret;
1539 if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire
1540 ret = x;
1541 } else {
1542 // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
1543 // only execute this if Q_ASSERTs are enabled
1544 Q_ASSERT((x->weakref.storeRelaxed(0), true));
1545 ::delete x;
1546 ret->weakref.ref();
1547 }
1548 return ret;
1549}
1550
1551/**
1552 \internal
1553 Returns a QSharedPointer<QObject> if the variant contains
1554 a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1555*/
1556QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
1557{
1558 Q_ASSERT(variant.metaType().flags() & QMetaType::SharedPointerToQObject);
1559 return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
1560}
1561
1562/**
1563 \internal
1564 Returns a QWeakPointer<QObject> if the variant contains
1565 a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1566*/
1567QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
1568{
1569 Q_ASSERT(variant.metaType().flags() & QMetaType::WeakPointerToQObject ||
1570 variant.metaType().flags() & QMetaType::TrackingPointerToQObject);
1571 return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
1572}
1573
1574QT_END_NAMESPACE
1575
1576#endif
1577
1578
1579
1580//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1581# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1582# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1583# define BACKTRACE_SUPPORTED
1584# elif defined(Q_OS_DARWIN)
1585# define BACKTRACE_SUPPORTED
1586# endif
1587# endif
1588
1589# if defined(BACKTRACE_SUPPORTED)
1590# include <sys/types.h>
1591# include <execinfo.h>
1592# include <stdio.h>
1593# include <unistd.h>
1594# include <sys/wait.h>
1595
1596QT_BEGIN_NAMESPACE
1597
1598static inline QByteArray saveBacktrace() __attribute__((always_inline));
1599static inline QByteArray saveBacktrace()
1600{
1601 static const int maxFrames = 32;
1602
1603 QByteArray stacktrace;
1604 stacktrace.resize(sizeof(void*) * maxFrames);
1605 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1606 stacktrace.resize(sizeof(void*) * stack_size);
1607
1608 return stacktrace;
1609}
1610
1611static void printBacktrace(QByteArray stacktrace)
1612{
1613 void *const *stack = (void *const *)stacktrace.constData();
1614 int stack_size = stacktrace.size() / sizeof(void*);
1615 char **stack_symbols = backtrace_symbols(stack, stack_size);
1616
1617 int filter[2];
1618 pid_t child = -1;
1619 if (pipe(filter) != -1)
1620 child = fork();
1621 if (child == 0) {
1622 // child process
1623 dup2(fileno(stderr), fileno(stdout));
1624 dup2(filter[0], fileno(stdin));
1625 close(filter[0]);
1626 close(filter[1]);
1627 execlp("c++filt", "c++filt", "-n", NULL);
1628
1629 // execlp failed
1630 execl("/bin/cat", "/bin/cat", NULL);
1631 _exit(127);
1632 }
1633
1634 // parent process
1635 close(filter[0]);
1636 FILE *output;
1637 if (child == -1) {
1638 // failed forking
1639 close(filter[1]);
1640 output = stderr;
1641 } else {
1642 output = fdopen(filter[1], "w");
1643 }
1644
1645 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1646 for (int i = 0; i < stack_size; ++i) {
1647 if (strlen(stack_symbols[i]))
1648 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1649 else
1650 fprintf(output, "#%-2d %p\n", i, stack[i]);
1651 }
1652
1653 if (child != -1) {
1654 fclose(output);
1655 waitpid(child, 0, 0);
1656 }
1657}
1658
1659QT_END_NAMESPACE
1660
1661# endif // BACKTRACE_SUPPORTED
1662
1663namespace {
1664 QT_USE_NAMESPACE
1665 struct Data {
1666 const volatile void *pointer;
1667# ifdef BACKTRACE_SUPPORTED
1669# endif
1670 };
1671
1673 {
1674 public:
1675 QMutex mutex;
1676 QHash<const void *, Data> dPointers;
1677 QHash<const volatile void *, const void *> dataPointers;
1678 };
1679}
1680
1681Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1682
1683QT_BEGIN_NAMESPACE
1684
1685namespace QtSharedPointer {
1686 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1687}
1688
1689/*!
1690 \internal
1691*/
1692void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1693{
1694 KnownPointers *const kp = knownPointers();
1695 if (!kp)
1696 return; // end-game: the application is being destroyed already
1697
1698 if (!ptr) {
1699 // nullptr is allowed to be tracked by more than one QSharedPointer, so we
1700 // need something else to put in our tracking structures
1701 ptr = d_ptr;
1702 }
1703
1704 QMutexLocker lock(&kp->mutex);
1705 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1706
1707 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1708
1709 const void *other_d_ptr = kp->dataPointers.value(ptr, nullptr);
1710 if (Q_UNLIKELY(other_d_ptr)) {
1711# ifdef BACKTRACE_SUPPORTED
1712 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1713# endif
1714 qFatal("QSharedPointer: internal self-check failed: pointer %p was already tracked "
1715 "by another QSharedPointer object %p", ptr, other_d_ptr);
1716 }
1717
1718 Data data;
1719 data.pointer = ptr;
1720# ifdef BACKTRACE_SUPPORTED
1721 data.backtrace = saveBacktrace();
1722# endif
1723
1724 kp->dPointers.insert(d_ptr, data);
1725 kp->dataPointers.insert(ptr, d_ptr);
1726 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1727}
1728
1729/*!
1730 \internal
1731*/
1732void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1733{
1734 KnownPointers *const kp = knownPointers();
1735 if (!kp)
1736 return; // end-game: the application is being destroyed already
1737
1738 QMutexLocker lock(&kp->mutex);
1739
1740 const auto it = kp->dPointers.constFind(d_ptr);
1741 if (Q_UNLIKELY(it == kp->dPointers.cend())) {
1742 qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1743 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1744 "in your code.", d_ptr);
1745 }
1746
1747 const auto it2 = kp->dataPointers.constFind(it->pointer);
1748 Q_ASSERT(it2 != kp->dataPointers.cend());
1749
1750 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1751
1752 // remove entries
1753 kp->dataPointers.erase(it2);
1754 kp->dPointers.erase(it);
1755 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1756}
1757
1758/*!
1759 \internal
1760 Called by the QSharedPointer autotest
1761*/
1762void QtSharedPointer::internalSafetyCheckCleanCheck()
1763{
1764# ifdef QT_BUILD_INTERNAL
1765 KnownPointers *const kp = knownPointers();
1766 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1767
1768 if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
1769 qFatal("Internal consistency error: the number of pointers is not equal!");
1770
1771 if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
1772 qFatal("Pointer cleaning failed: %d entries remaining", int(kp->dPointers.size()));
1773# endif
1774}
1775
1776QT_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