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 &QWeakPointer<T>::operator=(const QWeakPointer<T> &other)
849
850 Makes this object share \a other's pointer. The current pointer
851 reference is discarded but is not deleted.
852
853 If \tt T is a derived type of the template parameter of this
854 class, QWeakPointer will perform an automatic cast. Otherwise,
855 you will get a compiler error.
856*/
857
858/*!
859 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QSharedPointer<T> &other)
860
861 Makes this object share \a other's pointer. The current pointer
862 reference is discarded but is not deleted.
863
864 If \tt T is a derived type of the template parameter of this
865 class, QWeakPointer will perform an automatic cast. Otherwise,
866 you will get a compiler error.
867*/
868
869/*!
870 \fn template <class T> void QWeakPointer<T>::swap(QWeakPointer<T> &other)
871 \since 5.4
872 \memberswap{weak pointer instance}
873*/
874
875/*!
876 \fn template <class T> bool QWeakPointer<T>::isNull() const
877
878 Returns \c true if this object refers to \nullptr.
879
880 Note that, due to the nature of weak references, the pointer that
881 QWeakPointer references can become \nullptr at any moment, so
882 the value returned from this function can change from false to
883 true from one call to the next.
884*/
885
886/*!
887 \fn template <class T> QWeakPointer<T>::operator bool() const
888
889 Returns \c true if the contained pointer is not \nullptr.
890 This function is suitable for use in \tt if-constructs, like:
891
892 \snippet code/src_corelib_tools_qsharedpointer.cpp 8
893
894 Note that, due to the nature of weak references, the pointer that
895 QWeakPointer references can become \nullptr at any moment, so
896 the value returned from this function can change from true to
897 false from one call to the next.
898
899 \sa isNull()
900*/
901
902/*!
903 \fn template <class T> bool QWeakPointer<T>::operator !() const
904
905 Returns \c true if this object refers to \nullptr.
906 This function is suitable for use in \tt if-constructs, like:
907
908 \snippet code/src_corelib_tools_qsharedpointer.cpp 9
909
910 Note that, due to the nature of weak references, the pointer that
911 QWeakPointer references can become \nullptr at any moment, so
912 the value returned from this function can change from false to
913 true from one call to the next.
914
915 \sa isNull()
916*/
917
918/*!
919 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::toStrongRef() const
920
921 Promotes this weak reference to a strong one and returns a
922 QSharedPointer object holding that reference. When promoting to
923 QSharedPointer, this function verifies if the object has been deleted
924 already or not. If it hasn't, this function increases the reference
925 count to the shared object, thus ensuring that it will not get
926 deleted.
927
928 Since this function can fail to obtain a valid strong reference to the
929 shared object, you should always verify if the conversion succeeded,
930 by calling QSharedPointer::isNull() on the returned object.
931
932 For example, the following code promotes a QWeakPointer that was held
933 to a strong reference and, if it succeeded, it prints the value of the
934 integer that was held:
935
936 \snippet code/src_corelib_tools_qsharedpointer.cpp 12
937
938 \sa QSharedPointer::QSharedPointer()
939*/
940
941/*!
942 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::lock() const
943 \since 5.4
944
945 Same as toStrongRef().
946
947 This function is provided for API compatibility with std::weak_ptr.
948*/
949
950/*!
951 \fn template <class T> void QWeakPointer<T>::clear()
952
953 Clears this QWeakPointer object, dropping the reference that it
954 may have had to the pointer.
955*/
956
957/*!
958 \fn template <class T> QSharedPointer<T> QEnableSharedFromThis<T>::sharedFromThis()
959 \since 5.4
960
961 If \c this (that is, the subclass instance invoking this method) is being
962 managed by a QSharedPointer, returns a shared pointer instance pointing to
963 \c this; otherwise returns a null QSharedPointer.
964*/
965
966/*!
967 \fn template <class T> QSharedPointer<const T> QEnableSharedFromThis<T>::sharedFromThis() const
968 \overload
969 \since 5.4
970
971 Const overload of sharedFromThis().
972*/
973
974/*!
975 \fn template <class T> qHash(const QSharedPointer<T> &key, size_t seed)
976 \qhashold{QSharedPointer}
977 \since 5.0
978*/
979
980/*!
981 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &lhs, const QSharedPointer<X> &rhs)
982 \relates QSharedPointer
983
984 Returns \c true if \a lhs and \a rhs refer to the same pointer.
985
986//! [qsharedpointer-different-template-parameters]
987 If \a rhs's template parameter is different from \a lhs's,
988 QSharedPointer first needs to ensure that they are compatible types.
989 It will attempt to perform an automatic \tt static_cast to convert
990 the types \tt T and \tt X to their composite pointer type.
991 If \a rhs's template parameter is not a base or a derived type from
992 \a lhs's, you will get a compiler error.
993//! [qsharedpointer-different-template-parameters]
994*/
995
996/*!
997 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &lhs, const QSharedPointer<X> &rhs)
998 \relates QSharedPointer
999
1000 Returns \c true if \a lhs and \a rhs refer to distinct pointers.
1001
1002 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1003*/
1004
1005/*!
1006 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &lhs, const X *rhs)
1007 \relates QSharedPointer
1008
1009 Returns \c true if \a lhs and \a rhs refer to the same pointer.
1010
1011 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1012*/
1013
1014/*!
1015 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &lhs, const X *rhs)
1016 \relates QSharedPointer
1017
1018 Returns \c true if \a lhs and \a rhs refer to distinct pointers.
1019
1020 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1021*/
1022
1023/*!
1024 \fn template<class T, class X> bool operator==(const T *lhs, const QSharedPointer<X> &rhs)
1025 \relates QSharedPointer
1026
1027 Returns \c true if the pointer \a lhs is the
1028 same pointer as that referenced by \a rhs.
1029
1030 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1031*/
1032
1033/*!
1034 \fn template<class T, class X> bool operator!=(const T *lhs, const QSharedPointer<X> &rhs)
1035 \relates QSharedPointer
1036
1037 Returns \c true if the pointer \a lhs is not the
1038 same pointer as that referenced by \a rhs.
1039
1040 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1041*/
1042
1043/*!
1044 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1045 \relates QWeakPointer
1046
1047 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1048
1049 If \a ptr2's template parameter is different from \a ptr1's,
1050 QSharedPointer will attempt to perform an automatic \tt static_cast
1051 to ensure that the pointers being compared are equal. If \a ptr2's
1052 template parameter is not a base or a derived type from
1053 \a ptr1's, you will get a compiler error.
1054*/
1055
1056/*!
1057 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1058 \relates QWeakPointer
1059
1060 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1061
1062 If \a ptr2's template parameter is different from \a ptr1's,
1063 QSharedPointer will attempt to perform an automatic \tt static_cast
1064 to ensure that the pointers being compared are equal. If \a ptr2's
1065 template parameter is not a base or a derived type from
1066 \a ptr1's, you will get a compiler error.
1067*/
1068
1069/*!
1070 \fn template<class T, class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1071 \relates QWeakPointer
1072
1073 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1074
1075 If \a ptr2's template parameter is different from \a ptr1's,
1076 QSharedPointer will attempt to perform an automatic \tt static_cast
1077 to ensure that the pointers being compared are equal. If \a ptr2's
1078 template parameter is not a base or a derived type from
1079 \a ptr1's, you will get a compiler error.
1080*/
1081
1082/*!
1083 \fn template <class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t)
1084 \relates QSharedPointer
1085 \since 5.8
1086
1087 Returns \c true if \a lhs refers to \nullptr.
1088
1089 \sa QSharedPointer::isNull()
1090*/
1091
1092/*!
1093 \fn template <class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs)
1094 \relates QSharedPointer
1095 \since 5.8
1096
1097 Returns \c true if \a rhs refers to \nullptr.
1098
1099 \sa QSharedPointer::isNull()
1100*/
1101
1102/*!
1103 \fn template <class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t)
1104 \relates QSharedPointer
1105 \since 5.8
1106
1107 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1108
1109 \sa QSharedPointer::isNull()
1110*/
1111
1112/*!
1113 \fn template <class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs)
1114 \relates QSharedPointer
1115 \since 5.8
1116
1117 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1118
1119 \sa QSharedPointer::isNull()
1120*/
1121
1122/*!
1123 \fn template <class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t)
1124 \relates QWeakPointer
1125 \since 5.8
1126
1127 Returns \c true if \a lhs refers to \nullptr.
1128
1129 \sa QWeakPointer::isNull()
1130*/
1131
1132/*!
1133 \fn template <class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs)
1134 \relates QWeakPointer
1135 \since 5.8
1136
1137 Returns \c true if \a rhs refers to \nullptr.
1138
1139 \sa QWeakPointer::isNull()
1140*/
1141
1142/*!
1143 \fn template <class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t)
1144 \relates QWeakPointer
1145 \since 5.8
1146
1147 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1148
1149 \sa QWeakPointer::isNull()
1150*/
1151
1152/*!
1153 \fn template <class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs)
1154 \relates QWeakPointer
1155 \since 5.8
1156
1157 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1158
1159 \sa QWeakPointer::isNull()
1160*/
1161
1162/*!
1163 \fn template<class T, class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1164 \relates QWeakPointer
1165
1166 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1167
1168 If \a ptr2's template parameter is different from \a ptr1's,
1169 QSharedPointer will attempt to perform an automatic \tt static_cast
1170 to ensure that the pointers being compared are equal. If \a ptr2's
1171 template parameter is not a base or a derived type from
1172 \a ptr1's, you will get a compiler error.
1173*/
1174
1175/*!
1176 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
1177 \relates QSharedPointer
1178
1179 Returns a shared pointer to the pointer held by \a other, cast to
1180 type \tt X. The types \tt T and \tt X must belong to one
1181 hierarchy for the \tt static_cast to succeed.
1182
1183 Note that \tt X must have the same cv-qualifiers (\tt const and
1184 \tt volatile) that \tt T has, or the code will fail to
1185 compile. Use qSharedPointerConstCast to cast away the constness.
1186
1187 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1188*/
1189
1190/*!
1191 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(QSharedPointer<T> &&other)
1192 \relates QSharedPointer
1193 \since 6.9
1194 \overload qSharedPointerCast(const QSharedPointer<T> &other)
1195
1196 \include qsharedpointer.cpp {cast-overload-for-arg} {other}
1197
1198 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1199*/
1200
1201/*!
1202 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
1203 \relates QSharedPointer
1204 \relates QWeakPointer
1205
1206 Returns a shared pointer to the pointer held by \a other, cast to
1207 type \tt X. The types \tt T and \tt X must belong to one
1208 hierarchy for the \tt static_cast to succeed.
1209
1210 The \a other object is converted first to a strong reference. If
1211 that conversion fails (because the object it's pointing to has
1212 already been deleted), this function returns a null
1213 QSharedPointer.
1214
1215 Note that \tt X must have the same cv-qualifiers (\tt const and
1216 \tt volatile) that \tt T has, or the code will fail to
1217 compile. Use qSharedPointerConstCast to cast away the constness.
1218
1219 \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1220*/
1221
1222/*!
1223 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1224 \relates QSharedPointer
1225
1226 Returns a shared pointer to the pointer held by \a src, using a
1227 dynamic cast to type \tt X to obtain an internal pointer of the
1228 appropriate type. If the \tt dynamic_cast fails, the object
1229 returned will be null.
1230
1231 Note that \tt X must have the same cv-qualifiers (\tt const and
1232 \tt volatile) that \tt T has, or the code will fail to
1233 compile. Use qSharedPointerConstCast to cast away the constness.
1234
1235 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1236*/
1237
1238/*!
1239 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(QSharedPointer<T> &&src)
1240 \relates QSharedPointer
1241 \since 6.9
1242 \overload qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1243
1244 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1245
1246 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1247*/
1248
1249/*!
1250 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
1251 \relates QSharedPointer
1252 \relates QWeakPointer
1253
1254 Returns a shared pointer to the pointer held by \a src, using a
1255 dynamic cast to type \tt X to obtain an internal pointer of the
1256 appropriate type. If the \tt dynamic_cast fails, the object
1257 returned will be null.
1258
1259 The \a src object is converted first to a strong reference. If
1260 that conversion fails (because the object it's pointing to has
1261 already been deleted), this function also returns a null
1262 QSharedPointer.
1263
1264 Note that \tt X must have the same cv-qualifiers (\tt const and
1265 \tt volatile) that \tt T has, or the code will fail to
1266 compile. Use qSharedPointerConstCast to cast away the constness.
1267
1268 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1269*/
1270
1271/*!
1272 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
1273 \relates QSharedPointer
1274
1275 Returns a shared pointer to the pointer held by \a src, cast to
1276 type \tt X. The types \tt T and \tt X must belong to one
1277 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1278 volatile differences between \tt T and \tt X are ignored.
1279
1280 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1281*/
1282
1283/*!
1284 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(QSharedPointer<T> &&src)
1285 \relates QSharedPointer
1286 \since 6.9
1287 \overload qSharedPointerConstCast(const QSharedPointer<T> &src)
1288
1289 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1290
1291 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1292*/
1293
1294/*!
1295 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
1296 \relates QSharedPointer
1297 \relates QWeakPointer
1298
1299 Returns a shared pointer to the pointer held by \a src, cast to
1300 type \tt X. The types \tt T and \tt X must belong to one
1301 hierarchy for the \tt const_cast to succeed. The \tt const and
1302 \tt volatile differences between \tt T and \tt X are ignored.
1303
1304 The \a src object is converted first to a strong reference. If
1305 that conversion fails (because the object it's pointing to has
1306 already been deleted), this function returns a null
1307 QSharedPointer.
1308
1309 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
1310*/
1311
1312/*!
1313 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
1314 \relates QSharedPointer
1315 \since 4.6
1316
1317 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1318
1319 Returns a shared pointer to the pointer held by \a src, using a
1320 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1321 appropriate type. If the \tt qobject_cast fails, the object
1322 returned will be null.
1323
1324 Note that \tt X must have the same cv-qualifiers (\tt const and
1325 \tt volatile) that \tt T has, or the code will fail to
1326 compile. Use qSharedPointerConstCast to cast away the constness.
1327
1328 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1329*/
1330
1331/*!
1332 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(QSharedPointer<T> &&src)
1333 \relates QSharedPointer
1334 \since 6.9
1335 \overload qSharedPointerObjectCast(const QSharedPointer<T> &src)
1336
1337 \include qsharedpointer.cpp {cast-overload-for-arg} {src}
1338
1339 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1340*/
1341
1342/*!
1343 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
1344 \relates QSharedPointer
1345 \since 5.14
1346
1347 Returns a shared pointer to the pointer held by \a src, using a
1348 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1349 appropriate type. If the \tt qobject_cast fails, the object
1350 returned will be null.
1351
1352 Note that \tt X must have the same cv-qualifiers (\tt const and
1353 \tt volatile) that \tt T has, or the code will fail to
1354 compile. Use const_pointer_cast to cast away the constness.
1355*/
1356
1357/*!
1358 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
1359 \relates QSharedPointer
1360 \since 5.14
1361
1362 Returns a shared pointer to the pointer held by \a src.
1363
1364 Same as qSharedPointerObjectCast(). This function is provided for STL
1365 compatibility.
1366*/
1367
1368/*!
1369 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
1370 \relates QSharedPointer
1371 \since 5.14
1372
1373 Returns a shared pointer to the pointer held by \a src, using a
1374 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1375 appropriate type.
1376
1377 If the \tt qobject_cast succeeds, the function will return a valid shared
1378 pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
1379 object returned will be null, and \a src will not be modified.
1380
1381 Note that \tt X must have the same cv-qualifiers (\tt const and
1382 \tt volatile) that \tt T has, or the code will fail to
1383 compile. Use const_pointer_cast to cast away the constness.
1384*/
1385
1386/*!
1387 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
1388 \relates QSharedPointer
1389 \since 5.14
1390
1391 Same as qSharedPointerObjectCast(). This function is provided for STL
1392 compatibility.
1393*/
1394
1395/*!
1396 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
1397 \relates QSharedPointer
1398 \relates QWeakPointer
1399 \since 4.6
1400
1401 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1402
1403 Returns a shared pointer to the pointer held by \a src, using a
1404 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1405 appropriate type. If the \tt qobject_cast fails, the object
1406 returned will be null.
1407
1408 The \a src object is converted first to a strong reference. If
1409 that conversion fails (because the object it's pointing to has
1410 already been deleted), this function also returns a null
1411 QSharedPointer.
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 qSharedPointerConstCast to cast away the constness.
1416
1417 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1418*/
1419
1420
1421/*!
1422 \fn template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
1423 \relates QWeakPointer
1424
1425 Returns a weak pointer to the pointer held by \a src, cast to
1426 type \tt X. The types \tt T and \tt X must belong to one
1427 hierarchy for the \tt static_cast to succeed.
1428
1429 Note that \tt X must have the same cv-qualifiers (\tt const and
1430 \tt volatile) that \tt T has, or the code will fail to
1431 compile. Use qSharedPointerConstCast to cast away the constness.
1432*/
1433
1434#include <qset.h>
1435#include <qmutex.h>
1436
1437#if !defined(QT_NO_QOBJECT)
1438#include "private/qobject_p.h"
1439
1441
1442QT6_ONLY(
1443/*!
1444 \internal
1445 This function is called for a just-created QObject \a obj, to enable
1446 the use of QSharedPointer and QWeakPointer in the future.
1447 */
1448void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1449{}
1450)
1451
1452QT6_ONLY(
1453/*!
1454 \internal
1455 This function is called when a QSharedPointer is created from a QWeakPointer
1456
1457 We check that the QWeakPointer was really created from a QSharedPointer, and
1458 not from a QObject.
1459*/
1460void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1461{
1462 if (strongref.loadRelaxed() < 0)
1463 qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1464}
1465)
1466
1467QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1468{
1469 Q_ASSERT(obj);
1470 QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
1471 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1472
1473 ExternalRefCountData *that = d->sharedRefcount.loadAcquire();
1474 if (that) {
1475 that->weakref.ref();
1476 return that;
1477 }
1478
1479 // we can create the refcount data because it doesn't exist
1480 ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
1481 x->strongref.storeRelaxed(-1);
1482 x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
1483 x->destroyer = nullptr;
1484
1485 ExternalRefCountData *ret;
1486 if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire
1487 ret = x;
1488 } else {
1489 // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
1490 // only execute this if Q_ASSERTs are enabled
1491 Q_ASSERT((x->weakref.storeRelaxed(0), true));
1492 ::delete x;
1493 ret->weakref.ref();
1494 }
1495 return ret;
1496}
1497
1498/**
1499 \internal
1500 Returns a QSharedPointer<QObject> if the variant contains
1501 a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1502*/
1503QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
1504{
1505 Q_ASSERT(variant.metaType().flags() & QMetaType::SharedPointerToQObject);
1506 return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
1507}
1508
1509/**
1510 \internal
1511 Returns a QWeakPointer<QObject> if the variant contains
1512 a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1513*/
1514QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
1515{
1516 Q_ASSERT(variant.metaType().flags() & QMetaType::WeakPointerToQObject ||
1517 variant.metaType().flags() & QMetaType::TrackingPointerToQObject);
1518 return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
1519}
1520
1521QT_END_NAMESPACE
1522
1523#endif
1524
1525
1526
1527//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1528# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1529# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1530# define BACKTRACE_SUPPORTED
1531# elif defined(Q_OS_DARWIN)
1532# define BACKTRACE_SUPPORTED
1533# endif
1534# endif
1535
1536# if defined(BACKTRACE_SUPPORTED)
1537# include <sys/types.h>
1538# include <execinfo.h>
1539# include <stdio.h>
1540# include <unistd.h>
1541# include <sys/wait.h>
1542
1543QT_BEGIN_NAMESPACE
1544
1545static inline QByteArray saveBacktrace() __attribute__((always_inline));
1546static inline QByteArray saveBacktrace()
1547{
1548 static const int maxFrames = 32;
1549
1550 QByteArray stacktrace;
1551 stacktrace.resize(sizeof(void*) * maxFrames);
1552 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1553 stacktrace.resize(sizeof(void*) * stack_size);
1554
1555 return stacktrace;
1556}
1557
1558static void printBacktrace(QByteArray stacktrace)
1559{
1560 void *const *stack = (void *const *)stacktrace.constData();
1561 int stack_size = stacktrace.size() / sizeof(void*);
1562 char **stack_symbols = backtrace_symbols(stack, stack_size);
1563
1564 int filter[2];
1565 pid_t child = -1;
1566 if (pipe(filter) != -1)
1567 child = fork();
1568 if (child == 0) {
1569 // child process
1570 dup2(fileno(stderr), fileno(stdout));
1571 dup2(filter[0], fileno(stdin));
1572 close(filter[0]);
1573 close(filter[1]);
1574 execlp("c++filt", "c++filt", "-n", NULL);
1575
1576 // execlp failed
1577 execl("/bin/cat", "/bin/cat", NULL);
1578 _exit(127);
1579 }
1580
1581 // parent process
1582 close(filter[0]);
1583 FILE *output;
1584 if (child == -1) {
1585 // failed forking
1586 close(filter[1]);
1587 output = stderr;
1588 } else {
1589 output = fdopen(filter[1], "w");
1590 }
1591
1592 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1593 for (int i = 0; i < stack_size; ++i) {
1594 if (strlen(stack_symbols[i]))
1595 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1596 else
1597 fprintf(output, "#%-2d %p\n", i, stack[i]);
1598 }
1599
1600 if (child != -1) {
1601 fclose(output);
1602 waitpid(child, 0, 0);
1603 }
1604}
1605
1606QT_END_NAMESPACE
1607
1608# endif // BACKTRACE_SUPPORTED
1609
1610namespace {
1611 QT_USE_NAMESPACE
1612 struct Data {
1613 const volatile void *pointer;
1614# ifdef BACKTRACE_SUPPORTED
1616# endif
1617 };
1618
1620 {
1621 public:
1622 QMutex mutex;
1623 QHash<const void *, Data> dPointers;
1624 QHash<const volatile void *, const void *> dataPointers;
1625 };
1626}
1627
1628Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1629
1630QT_BEGIN_NAMESPACE
1631
1632namespace QtSharedPointer {
1633 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1634}
1635
1636/*!
1637 \internal
1638*/
1639void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1640{
1641 KnownPointers *const kp = knownPointers();
1642 if (!kp)
1643 return; // end-game: the application is being destroyed already
1644
1645 if (!ptr) {
1646 // nullptr is allowed to be tracked by more than one QSharedPointer, so we
1647 // need something else to put in our tracking structures
1648 ptr = d_ptr;
1649 }
1650
1651 QMutexLocker lock(&kp->mutex);
1652 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1653
1654 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1655
1656 const void *other_d_ptr = kp->dataPointers.value(ptr, nullptr);
1657 if (Q_UNLIKELY(other_d_ptr)) {
1658# ifdef BACKTRACE_SUPPORTED
1659 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1660# endif
1661 qFatal("QSharedPointer: internal self-check failed: pointer %p was already tracked "
1662 "by another QSharedPointer object %p", ptr, other_d_ptr);
1663 }
1664
1665 Data data;
1666 data.pointer = ptr;
1667# ifdef BACKTRACE_SUPPORTED
1668 data.backtrace = saveBacktrace();
1669# endif
1670
1671 kp->dPointers.insert(d_ptr, data);
1672 kp->dataPointers.insert(ptr, d_ptr);
1673 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1674}
1675
1676/*!
1677 \internal
1678*/
1679void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1680{
1681 KnownPointers *const kp = knownPointers();
1682 if (!kp)
1683 return; // end-game: the application is being destroyed already
1684
1685 QMutexLocker lock(&kp->mutex);
1686
1687 const auto it = kp->dPointers.constFind(d_ptr);
1688 if (Q_UNLIKELY(it == kp->dPointers.cend())) {
1689 qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1690 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1691 "in your code.", d_ptr);
1692 }
1693
1694 const auto it2 = kp->dataPointers.constFind(it->pointer);
1695 Q_ASSERT(it2 != kp->dataPointers.cend());
1696
1697 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1698
1699 // remove entries
1700 kp->dataPointers.erase(it2);
1701 kp->dPointers.erase(it);
1702 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1703}
1704
1705/*!
1706 \internal
1707 Called by the QSharedPointer autotest
1708*/
1709void QtSharedPointer::internalSafetyCheckCleanCheck()
1710{
1711# ifdef QT_BUILD_INTERNAL
1712 KnownPointers *const kp = knownPointers();
1713 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1714
1715 if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
1716 qFatal("Internal consistency error: the number of pointers is not equal!");
1717
1718 if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
1719 qFatal("Pointer cleaning failed: %d entries remaining", int(kp->dPointers.size()));
1720# endif
1721}
1722
1723QT_END_NAMESPACE
QHash< const void *, Data > dPointers
QHash< const volatile void *, const void * > dataPointers
const volatile void * pointer