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