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 This constructor participates in overload resolution only if \c{X*}
473 implicitly converts to \c{T*}.
474
475 \since 5.6
476*/
477
478/*!
479 \fn template <class T> template <class X> QSharedPointer<T>::operator=(QSharedPointer<X> &&other)
480
481 Move-assigns \a other to this QSharedPointer instance.
482
483 This assignment operator participates in overload resolution only if \c{X*}
484 implicitly converts to \c{T*}.
485
486 \since 5.6
487*/
488
489/*!
490 \fn template <class T> QSharedPointer<T>::QSharedPointer(const QWeakPointer<T> &other)
491
492 Creates a QSharedPointer by promoting the weak reference \a other
493 to strong reference and sharing its pointer.
494
495 If \tt T is a derived type of the template parameter of this
496 class, QSharedPointer will perform an automatic cast. Otherwise,
497 you will get a compiler error.
498
499 \sa QWeakPointer::toStrongRef()
500*/
501
502/*!
503 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QSharedPointer<T> &other)
504
505 Makes this object share \a other's pointer. The current pointer
506 reference is discarded and, if it was the last, the pointer will
507 be deleted.
508
509 If \tt T is a derived type of the template parameter of this
510 class, QSharedPointer will perform an automatic cast. Otherwise,
511 you will get a compiler error.
512*/
513
514/*!
515 \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QWeakPointer<T> &other)
516
517 Promotes \a other to a strong reference and makes this object
518 share a reference to the pointer referenced by it. The current pointer
519 reference is discarded and, if it was the last, the pointer will
520 be deleted.
521
522 If \tt T is a derived type of the template parameter of this
523 class, QSharedPointer will perform an automatic cast. Otherwise,
524 you will get a compiler error.
525*/
526
527/*!
528 \fn template <class T> void QSharedPointer<T>::swap(QSharedPointer<T> &other);
529 \since 5.3
530 \memberswap{shared pointer instance}
531*/
532
533/*!
534 \fn template <class T> T *QSharedPointer<T>::data() const
535
536 Returns the value of the pointer referenced by this object.
537
538 Note: do not delete the pointer returned by this function or pass
539 it to another function that could delete it, including creating
540 QSharedPointer or QWeakPointer objects.
541*/
542
543/*!
544 \fn template <class T> T *QSharedPointer<T>::get() const
545 \since 5.11
546
547 Same as data().
548
549 This function is provided for API compatibility with \c{std::shared_ptr}.
550*/
551
552/*!
553 \fn template <class T> T &QSharedPointer<T>::operator *() const
554
555 Provides access to the shared pointer's members.
556
557 If the contained pointer is \nullptr, behavior is undefined.
558 \sa isNull()
559*/
560
561/*!
562 \fn template <class T> T *QSharedPointer<T>::operator ->() const
563
564 Provides access to the shared pointer's members.
565
566 If the contained pointer is \nullptr, behavior is undefined.
567 \sa isNull()
568*/
569
570/*!
571 \fn template <class T> bool QSharedPointer<T>::isNull() const
572
573 Returns \c true if this object refers to \nullptr.
574*/
575
576/*!
577 \fn template <class T> QSharedPointer<T>::operator bool() const
578
579 Returns \c true if the contained pointer is not \nullptr.
580 This function is suitable for use in \tt if-constructs, like:
581
582 \snippet code/src_corelib_tools_qsharedpointer.cpp 4
583
584 \sa isNull()
585*/
586
587/*!
588 \fn template <class T> bool QSharedPointer<T>::operator !() const
589
590 Returns \c true if this object refers to \nullptr.
591 This function is suitable for use in \tt if-constructs, like:
592
593 \snippet code/src_corelib_tools_qsharedpointer.cpp 5
594
595 \sa isNull()
596*/
597
598/*!
599 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::staticCast() const
600
601 Performs a static cast from this pointer's type to \tt X and returns
602 a QSharedPointer that shares the reference. This function can be
603 used for up- and for down-casting, but is more useful for
604 up-casting.
605
606 Note: the template type \c X must have the same const and volatile
607 qualifiers as the template of this object, or the cast will
608 fail. Use constCast() if you need to drop those qualifiers.
609
610 \sa dynamicCast(), constCast(), qSharedPointerCast()
611*/
612
613/*!
614 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::dynamicCast() const
615
616 Performs a dynamic cast from this pointer's type to \tt X and
617 returns a QSharedPointer that shares the reference. If this
618 function is used to up-cast, then QSharedPointer will perform a \tt
619 dynamic_cast, which means that if the object being pointed by this
620 QSharedPointer is not of type \tt X, the returned object will be
621 null.
622
623 Note: the template type \c X must have the same const and volatile
624 qualifiers as the template of this object, or the cast will
625 fail. Use constCast() if you need to drop those qualifiers.
626
627 \sa qSharedPointerDynamicCast()
628*/
629
630/*!
631 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::constCast() const
632
633 Performs a \tt const_cast from this pointer's type to \tt X and returns
634 a QSharedPointer that shares the reference. This function can be
635 used for up- and for down-casting, but is more useful for
636 up-casting.
637
638 \sa isNull(), qSharedPointerConstCast()
639*/
640
641/*!
642 \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::objectCast() const
643 \since 4.6
644
645 Performs a \l qobject_cast() from this pointer's type to \tt X and
646 returns a QSharedPointer that shares the reference. If this
647 function is used to up-cast, then QSharedPointer will perform a \tt
648 qobject_cast, which means that if the object being pointed by this
649 QSharedPointer is not of type \tt X, the returned object will be
650 null.
651
652 Note: the template type \c X must have the same const and volatile
653 qualifiers as the template of this object, or the cast will
654 fail. Use constCast() if you need to drop those qualifiers.
655
656 \sa qSharedPointerObjectCast()
657*/
658
659/*!
660 \fn template <class T> template <typename... Args> QSharedPointer<T> QSharedPointer<T>::create(Args &&... args)
661 \overload
662 \since 5.1
663
664 Creates a QSharedPointer object and allocates a new item of type \tt T. The
665 QSharedPointer internals and the object are allocated in one single memory
666 allocation, which could help reduce memory fragmentation in a long-running
667 application.
668
669 This function will attempt to call a constructor for type \tt T that can
670 accept all the arguments passed (\a args). Arguments will be perfectly-forwarded.
671*/
672
673/*!
674 \fn template <class T> QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
675
676 Returns a weak reference object that shares the pointer referenced
677 by this object.
678
679 \sa QWeakPointer::QWeakPointer()
680*/
681
682/*!
683 \fn template <class T> void QSharedPointer<T>::clear()
684
685 Clears this QSharedPointer object, dropping the reference that it
686 may have had to the pointer. If this was the last reference, then
687 the pointer itself will be deleted.
688*/
689
690/*!
691 \fn template <class T> void QSharedPointer<T>::reset()
692 \since 5.0
693
694 Same as clear(). For std::shared_ptr compatibility.
695*/
696
697/*!
698 \fn template <class T> void QSharedPointer<T>::reset(T *t)
699 \since 5.0
700
701 Resets this QSharedPointer object to point to \a t
702 instead. Equivalent to:
703 \snippet code/src_corelib_tools_qsharedpointer.cpp 6
704*/
705
706/*!
707 \fn template <class T> template <typename Deleter> void QSharedPointer<T>::reset(T *t, Deleter deleter)
708 \since 5.0
709
710 Resets this QSharedPointer object to point to \a t
711 instead, with the Deleter \a deleter. Equivalent to:
712 \snippet code/src_corelib_tools_qsharedpointer.cpp 7
713*/
714
715/*!
716 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_before(const QSharedPointer<X> &other) const noexcept
717 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_before(const QWeakPointer<X> &other) const noexcept
718 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_before(const QSharedPointer<X> &other) const noexcept
719 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_before(const QWeakPointer<X> &other) const noexcept
720 \since 6.7
721
722 Returns \c true if and only if this smart pointer precedes \a other
723 in an implementation-defined owner-based ordering. The ordering is such
724 that two smart pointers are considered equivalent if they are both
725 empty or if they both own the same object (even if their apparent type
726 and pointer are different).
727
728 \sa owner_equal
729*/
730
731/*!
732 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_equal(const QSharedPointer<X> &other) const noexcept
733 \fn template <class T> template <class X> bool QSharedPointer<T>::owner_equal(const QWeakPointer<X> &other) const noexcept
734 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_equal(const QSharedPointer<X> &other) const noexcept
735 \fn template <class T> template <class X> bool QWeakPointer<T>::owner_equal(const QWeakPointer<X> &other) const noexcept
736
737 \since 6.7
738
739 Returns \c true if and only if this smart pointer and \a other
740 share ownership.
741
742 \sa owner_before, owner_hash
743*/
744
745/*!
746 \fn template <class T> size_t QSharedPointer<T>::owner_hash() const noexcept
747 \fn template <class T> size_t QWeakPointer<T>::owner_hash() const noexcept
748
749 \since 6.7
750
751 Returns a owner-based hash value for this smart pointer object.
752 Smart pointers that compare equal (as per \c{owner_equal}) will
753 have an identical owner-based hash.
754
755 \sa owner_equal
756*/
757
758/*!
759 \fn template <class T> QWeakPointer<T>::QWeakPointer()
760
761 Creates a QWeakPointer that points to nothing.
762*/
763
764/*!
765 \fn template <class T> QWeakPointer<T>::~QWeakPointer()
766
767 Destroys this QWeakPointer object. The pointer referenced
768 by this object will not be deleted.
769*/
770
771/*!
772 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QWeakPointer<T> &other)
773
774 Creates a QWeakPointer that holds a weak reference to the
775 pointer referenced by \a other.
776
777 If \tt T is a derived type of the template parameter of this
778 class, QWeakPointer will perform an automatic cast. Otherwise,
779 you will get a compiler error.
780*/
781
782/*!
783 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QSharedPointer<T> &other)
784
785 Creates a QWeakPointer that holds a weak reference to the
786 pointer referenced by \a other.
787
788 If \tt T is a derived type of the template parameter of this
789 class, QWeakPointer will perform an automatic cast. Otherwise,
790 you will get a compiler error.
791*/
792
793/*!
794 \fn template <class T> QWeakPointer<T>::QWeakPointer(const QObject *other)
795 \since 4.6
796 \deprecated
797
798 Creates a QWeakPointer that holds a weak reference directly to the
799 QObject \a other. This constructor is only available if the template type
800 \tt T is QObject or derives from it (otherwise a compilation error will
801 result).
802
803 You can use this constructor with any QObject, even if they were not
804 created with \l QSharedPointer.
805
806 Note that QWeakPointers created this way on arbitrary QObjects usually
807 cannot be promoted to QSharedPointer.
808
809 \sa QSharedPointer, QPointer
810*/
811
812/*!
813 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QObject *other)
814 \since 4.6
815 \deprecated
816
817 Makes this QWeakPointer hold a weak reference directly to the QObject
818 \a other. This function is only available if the template type \tt T is
819 QObject or derives from it.
820
821 \sa QPointer
822*/
823
824/*!
825 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QWeakPointer<T> &other)
826
827 Makes this object share \a other's pointer. The current pointer
828 reference is discarded but is not deleted.
829
830 If \tt T is a derived type of the template parameter of this
831 class, QWeakPointer will perform an automatic cast. Otherwise,
832 you will get a compiler error.
833*/
834
835/*!
836 \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QSharedPointer<T> &other)
837
838 Makes this object share \a other's pointer. The current pointer
839 reference is discarded but is not deleted.
840
841 If \tt T is a derived type of the template parameter of this
842 class, QWeakPointer will perform an automatic cast. Otherwise,
843 you will get a compiler error.
844*/
845
846/*!
847 \fn template <class T> void QWeakPointer<T>::swap(QWeakPointer<T> &other)
848 \since 5.4
849 \memberswap{weak pointer instance}
850*/
851
852/*!
853 \fn template <class T> bool QWeakPointer<T>::isNull() const
854
855 Returns \c true if this object refers to \nullptr.
856
857 Note that, due to the nature of weak references, the pointer that
858 QWeakPointer references can become \nullptr at any moment, so
859 the value returned from this function can change from false to
860 true from one call to the next.
861*/
862
863/*!
864 \fn template <class T> QWeakPointer<T>::operator bool() const
865
866 Returns \c true if the contained pointer is not \nullptr.
867 This function is suitable for use in \tt if-constructs, like:
868
869 \snippet code/src_corelib_tools_qsharedpointer.cpp 8
870
871 Note that, due to the nature of weak references, the pointer that
872 QWeakPointer references can become \nullptr at any moment, so
873 the value returned from this function can change from true to
874 false from one call to the next.
875
876 \sa isNull()
877*/
878
879/*!
880 \fn template <class T> bool QWeakPointer<T>::operator !() const
881
882 Returns \c true if this object refers to \nullptr.
883 This function is suitable for use in \tt if-constructs, like:
884
885 \snippet code/src_corelib_tools_qsharedpointer.cpp 9
886
887 Note that, due to the nature of weak references, the pointer that
888 QWeakPointer references can become \nullptr at any moment, so
889 the value returned from this function can change from false to
890 true from one call to the next.
891
892 \sa isNull()
893*/
894
895/*!
896 \fn template <class T> T *QWeakPointer<T>::data() const
897 \since 4.6
898 \deprecated Use toStrongRef() instead, and data() on the returned QSharedPointer.
899
900 Returns the value of the pointer being tracked by this QWeakPointer,
901 \b without ensuring that it cannot get deleted. To have that guarantee,
902 use toStrongRef(), which returns a QSharedPointer object. If this
903 function can determine that the pointer has already been deleted, it
904 returns \nullptr.
905
906 It is ok to obtain the value of the pointer and using that value itself,
907 like for example in debugging statements:
908
909 \snippet code/src_corelib_tools_qsharedpointer.cpp 10
910
911 However, dereferencing the pointer is only allowed if you can guarantee
912 by external means that the pointer does not get deleted. For example,
913 if you can be certain that no other thread can delete it, nor the
914 functions that you may call.
915
916 If that is the case, then the following code is valid:
917
918 \snippet code/src_corelib_tools_qsharedpointer.cpp 11
919
920 Use this function with care.
921
922 \sa isNull(), toStrongRef()
923*/
924
925/*!
926 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::toStrongRef() const
927
928 Promotes this weak reference to a strong one and returns a
929 QSharedPointer object holding that reference. When promoting to
930 QSharedPointer, this function verifies if the object has been deleted
931 already or not. If it hasn't, this function increases the reference
932 count to the shared object, thus ensuring that it will not get
933 deleted.
934
935 Since this function can fail to obtain a valid strong reference to the
936 shared object, you should always verify if the conversion succeeded,
937 by calling QSharedPointer::isNull() on the returned object.
938
939 For example, the following code promotes a QWeakPointer that was held
940 to a strong reference and, if it succeeded, it prints the value of the
941 integer that was held:
942
943 \snippet code/src_corelib_tools_qsharedpointer.cpp 12
944
945 \sa QSharedPointer::QSharedPointer()
946*/
947
948/*!
949 \fn template <class T> QSharedPointer<T> QWeakPointer<T>::lock() const
950 \since 5.4
951
952 Same as toStrongRef().
953
954 This function is provided for API compatibility with std::weak_ptr.
955*/
956
957/*!
958 \fn template <class T> void QWeakPointer<T>::clear()
959
960 Clears this QWeakPointer object, dropping the reference that it
961 may have had to the pointer.
962*/
963
964/*!
965 \fn template <class T> QSharedPointer<T> QEnableSharedFromThis<T>::sharedFromThis()
966 \since 5.4
967
968 If \c this (that is, the subclass instance invoking this method) is being
969 managed by a QSharedPointer, returns a shared pointer instance pointing to
970 \c this; otherwise returns a null QSharedPointer.
971*/
972
973/*!
974 \fn template <class T> QSharedPointer<const T> QEnableSharedFromThis<T>::sharedFromThis() const
975 \overload
976 \since 5.4
977
978 Const overload of sharedFromThis().
979*/
980
981/*!
982 \fn template <class T> qHash(const QSharedPointer<T> &key, size_t seed)
983 \relates QSharedPointer
984
985 Returns the hash value for \a key, using \a seed to seed the calculation.
986
987 \since 5.0
988*/
989
990/*!
991 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &lhs, const QSharedPointer<X> &rhs)
992 \relates QSharedPointer
993
994 Returns \c true if \a lhs and \a rhs refer to the same pointer.
995
996//! [qsharedpointer-different-template-parameters]
997 If \a rhs's template parameter is different from \a lhs's,
998 QSharedPointer first needs to ensure that they are compatible types.
999 It will attempt to perform an automatic \tt static_cast to convert
1000 the types \tt T and \tt X to their composite pointer type.
1001 If \a rhs's template parameter is not a base or a derived type from
1002 \a lhs's, you will get a compiler error.
1003//! [qsharedpointer-different-template-parameters]
1004*/
1005
1006/*!
1007 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &lhs, const QSharedPointer<X> &rhs)
1008 \relates QSharedPointer
1009
1010 Returns \c true if \a lhs and \a rhs refer to distinct pointers.
1011
1012 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1013*/
1014
1015/*!
1016 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &lhs, const X *rhs)
1017 \relates QSharedPointer
1018
1019 Returns \c true if \a lhs and \a rhs refer to the same pointer.
1020
1021 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1022*/
1023
1024/*!
1025 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &lhs, const X *rhs)
1026 \relates QSharedPointer
1027
1028 Returns \c true if \a lhs and \a rhs refer to distinct pointers.
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 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 T *lhs, const QSharedPointer<X> &rhs)
1045 \relates QSharedPointer
1046
1047 Returns \c true if the pointer \a lhs is not the
1048 same pointer as that referenced by \a rhs.
1049
1050 \include qsharedpointer.cpp qsharedpointer-different-template-parameters
1051*/
1052
1053/*!
1054 \fn template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1055 \relates QWeakPointer
1056
1057 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1058
1059 If \a ptr2's template parameter is different from \a ptr1's,
1060 QSharedPointer will attempt to perform an automatic \tt static_cast
1061 to ensure that the pointers being compared are equal. If \a ptr2's
1062 template parameter is not a base or a derived type from
1063 \a ptr1's, you will get a compiler error.
1064*/
1065
1066/*!
1067 \fn template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
1068 \relates QWeakPointer
1069
1070 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1071
1072 If \a ptr2's template parameter is different from \a ptr1's,
1073 QSharedPointer will attempt to perform an automatic \tt static_cast
1074 to ensure that the pointers being compared are equal. If \a ptr2's
1075 template parameter is not a base or a derived type from
1076 \a ptr1's, you will get a compiler error.
1077*/
1078
1079/*!
1080 \fn template<class T, class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1081 \relates QWeakPointer
1082
1083 Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.
1084
1085 If \a ptr2's template parameter is different from \a ptr1's,
1086 QSharedPointer will attempt to perform an automatic \tt static_cast
1087 to ensure that the pointers being compared are equal. If \a ptr2's
1088 template parameter is not a base or a derived type from
1089 \a ptr1's, you will get a compiler error.
1090*/
1091
1092/*!
1093 \fn template <class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t)
1094 \relates QSharedPointer
1095 \since 5.8
1096
1097 Returns \c true if \a lhs refers to \nullptr.
1098
1099 \sa QSharedPointer::isNull()
1100*/
1101
1102/*!
1103 \fn template <class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs)
1104 \relates QSharedPointer
1105 \since 5.8
1106
1107 Returns \c true if \a rhs refers to \nullptr.
1108
1109 \sa QSharedPointer::isNull()
1110*/
1111
1112/*!
1113 \fn template <class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t)
1114 \relates QSharedPointer
1115 \since 5.8
1116
1117 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1118
1119 \sa QSharedPointer::isNull()
1120*/
1121
1122/*!
1123 \fn template <class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs)
1124 \relates QSharedPointer
1125 \since 5.8
1126
1127 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1128
1129 \sa QSharedPointer::isNull()
1130*/
1131
1132/*!
1133 \fn template <class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t)
1134 \relates QWeakPointer
1135 \since 5.8
1136
1137 Returns \c true if \a lhs refers to \nullptr.
1138
1139 \sa QWeakPointer::isNull()
1140*/
1141
1142/*!
1143 \fn template <class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs)
1144 \relates QWeakPointer
1145 \since 5.8
1146
1147 Returns \c true if \a rhs refers to \nullptr.
1148
1149 \sa QWeakPointer::isNull()
1150*/
1151
1152/*!
1153 \fn template <class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t)
1154 \relates QWeakPointer
1155 \since 5.8
1156
1157 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
1158
1159 \sa QWeakPointer::isNull()
1160*/
1161
1162/*!
1163 \fn template <class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs)
1164 \relates QWeakPointer
1165 \since 5.8
1166
1167 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
1168
1169 \sa QWeakPointer::isNull()
1170*/
1171
1172/*!
1173 \fn template<class T, class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
1174 \relates QWeakPointer
1175
1176 Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.
1177
1178 If \a ptr2's template parameter is different from \a ptr1's,
1179 QSharedPointer will attempt to perform an automatic \tt static_cast
1180 to ensure that the pointers being compared are equal. If \a ptr2's
1181 template parameter is not a base or a derived type from
1182 \a ptr1's, you will get a compiler error.
1183*/
1184
1185/*!
1186 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
1187 \relates QSharedPointer
1188
1189 Returns a shared pointer to the pointer held by \a other, cast to
1190 type \tt X. The types \tt T and \tt X must belong to one
1191 hierarchy for the \tt static_cast to succeed.
1192
1193 Note that \tt X must have the same cv-qualifiers (\tt const and
1194 \tt volatile) that \tt T has, or the code will fail to
1195 compile. Use qSharedPointerConstCast to cast away the constness.
1196
1197 \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1198*/
1199
1200/*!
1201 \fn template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
1202 \relates QSharedPointer
1203 \relates QWeakPointer
1204
1205 Returns a shared pointer to the pointer held by \a other, cast to
1206 type \tt X. The types \tt T and \tt X must belong to one
1207 hierarchy for the \tt static_cast to succeed.
1208
1209 The \a other object is converted first to a strong reference. If
1210 that conversion fails (because the object it's pointing to has
1211 already been deleted), this function returns a null
1212 QSharedPointer.
1213
1214 Note that \tt X must have the same cv-qualifiers (\tt const and
1215 \tt volatile) that \tt T has, or the code will fail to
1216 compile. Use qSharedPointerConstCast to cast away the constness.
1217
1218 \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
1219*/
1220
1221/*!
1222 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
1223 \relates QSharedPointer
1224
1225 Returns a shared pointer to the pointer held by \a src, using a
1226 dynamic cast to type \tt X to obtain an internal pointer of the
1227 appropriate type. If the \tt dynamic_cast fails, the object
1228 returned will be null.
1229
1230 Note that \tt X must have the same cv-qualifiers (\tt const and
1231 \tt volatile) that \tt T has, or the code will fail to
1232 compile. Use qSharedPointerConstCast to cast away the constness.
1233
1234 \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
1235*/
1236
1237/*!
1238 \fn template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
1239 \relates QSharedPointer
1240 \relates QWeakPointer
1241
1242 Returns a shared pointer to the pointer held by \a src, using a
1243 dynamic cast to type \tt X to obtain an internal pointer of the
1244 appropriate type. If the \tt dynamic_cast fails, the object
1245 returned will be null.
1246
1247 The \a src object is converted first to a strong reference. If
1248 that conversion fails (because the object it's pointing to has
1249 already been deleted), this function also returns a null
1250 QSharedPointer.
1251
1252 Note that \tt X must have the same cv-qualifiers (\tt const and
1253 \tt volatile) that \tt T has, or the code will fail to
1254 compile. Use qSharedPointerConstCast to cast away the constness.
1255
1256 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1257*/
1258
1259/*!
1260 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
1261 \relates QSharedPointer
1262
1263 Returns a shared pointer to the pointer held by \a src, cast to
1264 type \tt X. The types \tt T and \tt X must belong to one
1265 hierarchy for the \tt const_cast to succeed. The \tt const and \tt
1266 volatile differences between \tt T and \tt X are ignored.
1267
1268 \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
1269*/
1270
1271/*!
1272 \fn template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
1273 \relates QSharedPointer
1274 \relates QWeakPointer
1275
1276 Returns a shared pointer to the pointer held by \a src, cast to
1277 type \tt X. The types \tt T and \tt X must belong to one
1278 hierarchy for the \tt const_cast to succeed. The \tt const and
1279 \tt volatile differences between \tt T and \tt X are ignored.
1280
1281 The \a src object is converted first to a strong reference. If
1282 that conversion fails (because the object it's pointing to has
1283 already been deleted), this function returns a null
1284 QSharedPointer.
1285
1286 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
1287*/
1288
1289/*!
1290 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
1291 \relates QSharedPointer
1292 \since 4.6
1293
1294 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1295
1296 Returns a shared pointer to the pointer held by \a src, using a
1297 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1298 appropriate type. If the \tt qobject_cast fails, the object
1299 returned will be null.
1300
1301 Note that \tt X must have the same cv-qualifiers (\tt const and
1302 \tt volatile) that \tt T has, or the code will fail to
1303 compile. Use qSharedPointerConstCast to cast away the constness.
1304
1305 \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
1306*/
1307
1308/*!
1309 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
1310 \relates QSharedPointer
1311 \since 5.14
1312
1313 Returns a shared pointer to the pointer held by \a src, using a
1314 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1315 appropriate type. If the \tt qobject_cast fails, the object
1316 returned will be null.
1317
1318 Note that \tt X must have the same cv-qualifiers (\tt const and
1319 \tt volatile) that \tt T has, or the code will fail to
1320 compile. Use const_pointer_cast to cast away the constness.
1321*/
1322
1323/*!
1324 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
1325 \relates QSharedPointer
1326 \since 5.14
1327
1328 Returns a shared pointer to the pointer held by \a src.
1329
1330 Same as qSharedPointerObjectCast(). This function is provided for STL
1331 compatibility.
1332*/
1333
1334/*!
1335 \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
1336 \relates QSharedPointer
1337 \since 5.14
1338
1339 Returns a shared pointer to the pointer held by \a src, using a
1340 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1341 appropriate type.
1342
1343 If the \tt qobject_cast succeeds, the function will return a valid shared
1344 pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
1345 object returned will be null, and \a src will not be modified.
1346
1347 Note that \tt X must have the same cv-qualifiers (\tt const and
1348 \tt volatile) that \tt T has, or the code will fail to
1349 compile. Use const_pointer_cast to cast away the constness.
1350*/
1351
1352/*!
1353 \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
1354 \relates QSharedPointer
1355 \since 5.14
1356
1357 Same as qSharedPointerObjectCast(). This function is provided for STL
1358 compatibility.
1359*/
1360
1361/*!
1362 \fn template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
1363 \relates QSharedPointer
1364 \relates QWeakPointer
1365 \since 4.6
1366
1367 \brief The qSharedPointerObjectCast function is for casting a shared pointer.
1368
1369 Returns a shared pointer to the pointer held by \a src, using a
1370 \l qobject_cast() to type \tt X to obtain an internal pointer of the
1371 appropriate type. If the \tt qobject_cast fails, the object
1372 returned will be null.
1373
1374 The \a src object is converted first to a strong reference. If
1375 that conversion fails (because the object it's pointing to has
1376 already been deleted), this function also returns a null
1377 QSharedPointer.
1378
1379 Note that \tt X must have the same cv-qualifiers (\tt const and
1380 \tt volatile) that \tt T has, or the code will fail to
1381 compile. Use qSharedPointerConstCast to cast away the constness.
1382
1383 \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
1384*/
1385
1386
1387/*!
1388 \fn template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
1389 \relates QWeakPointer
1390
1391 Returns a weak pointer to the pointer held by \a src, cast to
1392 type \tt X. The types \tt T and \tt X must belong to one
1393 hierarchy for the \tt static_cast to succeed.
1394
1395 Note that \tt X must have the same cv-qualifiers (\tt const and
1396 \tt volatile) that \tt T has, or the code will fail to
1397 compile. Use qSharedPointerConstCast to cast away the constness.
1398*/
1399
1400#include <qset.h>
1401#include <qmutex.h>
1402
1403#if !defined(QT_NO_QOBJECT)
1404#include "private/qobject_p.h"
1405
1407
1408QT6_ONLY(
1409/*!
1410 \internal
1411 This function is called for a just-created QObject \a obj, to enable
1412 the use of QSharedPointer and QWeakPointer in the future.
1413 */
1414void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
1415{}
1416)
1417
1418QT6_ONLY(
1419/*!
1420 \internal
1421 This function is called when a QSharedPointer is created from a QWeakPointer
1422
1423 We check that the QWeakPointer was really created from a QSharedPointer, and
1424 not from a QObject.
1425*/
1426void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
1427{
1428 if (strongref.loadRelaxed() < 0)
1429 qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
1430}
1431)
1432
1433QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
1434{
1435 Q_ASSERT(obj);
1436 QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
1437 Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
1438
1439 ExternalRefCountData *that = d->sharedRefcount.loadRelaxed();
1440 if (that) {
1441 that->weakref.ref();
1442 return that;
1443 }
1444
1445 // we can create the refcount data because it doesn't exist
1446 ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
1447 x->strongref.storeRelaxed(-1);
1448 x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
1449
1450 ExternalRefCountData *ret;
1451 if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire
1452 ret = x;
1453 } else {
1454 // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
1455 // only execute this if Q_ASSERTs are enabled
1456 Q_ASSERT((x->weakref.storeRelaxed(0), true));
1457 ::delete x;
1458 ret->weakref.ref();
1459 }
1460 return ret;
1461}
1462
1463/**
1464 \internal
1465 Returns a QSharedPointer<QObject> if the variant contains
1466 a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1467*/
1468QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
1469{
1470 Q_ASSERT(variant.metaType().flags() & QMetaType::SharedPointerToQObject);
1471 return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
1472}
1473
1474/**
1475 \internal
1476 Returns a QWeakPointer<QObject> if the variant contains
1477 a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
1478*/
1479QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
1480{
1481 Q_ASSERT(variant.metaType().flags() & QMetaType::WeakPointerToQObject ||
1482 variant.metaType().flags() & QMetaType::TrackingPointerToQObject);
1483 return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
1484}
1485
1486QT_END_NAMESPACE
1487
1488#endif
1489
1490
1491
1492//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
1493# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
1494# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
1495# define BACKTRACE_SUPPORTED
1496# elif defined(Q_OS_DARWIN)
1497# define BACKTRACE_SUPPORTED
1498# endif
1499# endif
1500
1501# if defined(BACKTRACE_SUPPORTED)
1502# include <sys/types.h>
1503# include <execinfo.h>
1504# include <stdio.h>
1505# include <unistd.h>
1506# include <sys/wait.h>
1507
1508QT_BEGIN_NAMESPACE
1509
1510static inline QByteArray saveBacktrace() __attribute__((always_inline));
1511static inline QByteArray saveBacktrace()
1512{
1513 static const int maxFrames = 32;
1514
1515 QByteArray stacktrace;
1516 stacktrace.resize(sizeof(void*) * maxFrames);
1517 int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
1518 stacktrace.resize(sizeof(void*) * stack_size);
1519
1520 return stacktrace;
1521}
1522
1523static void printBacktrace(QByteArray stacktrace)
1524{
1525 void *const *stack = (void *const *)stacktrace.constData();
1526 int stack_size = stacktrace.size() / sizeof(void*);
1527 char **stack_symbols = backtrace_symbols(stack, stack_size);
1528
1529 int filter[2];
1530 pid_t child = -1;
1531 if (pipe(filter) != -1)
1532 child = fork();
1533 if (child == 0) {
1534 // child process
1535 dup2(fileno(stderr), fileno(stdout));
1536 dup2(filter[0], fileno(stdin));
1537 close(filter[0]);
1538 close(filter[1]);
1539 execlp("c++filt", "c++filt", "-n", NULL);
1540
1541 // execlp failed
1542 execl("/bin/cat", "/bin/cat", NULL);
1543 _exit(127);
1544 }
1545
1546 // parent process
1547 close(filter[0]);
1548 FILE *output;
1549 if (child == -1) {
1550 // failed forking
1551 close(filter[1]);
1552 output = stderr;
1553 } else {
1554 output = fdopen(filter[1], "w");
1555 }
1556
1557 fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
1558 for (int i = 0; i < stack_size; ++i) {
1559 if (strlen(stack_symbols[i]))
1560 fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
1561 else
1562 fprintf(output, "#%-2d %p\n", i, stack[i]);
1563 }
1564
1565 if (child != -1) {
1566 fclose(output);
1567 waitpid(child, 0, 0);
1568 }
1569}
1570
1571QT_END_NAMESPACE
1572
1573# endif // BACKTRACE_SUPPORTED
1574
1575namespace {
1576 QT_USE_NAMESPACE
1577 struct Data {
1578 const volatile void *pointer;
1579# ifdef BACKTRACE_SUPPORTED
1581# endif
1582 };
1583
1585 {
1586 public:
1587 QMutex mutex;
1588 QHash<const void *, Data> dPointers;
1589 QHash<const volatile void *, const void *> dataPointers;
1590 };
1591}
1592
1593Q_GLOBAL_STATIC(KnownPointers, knownPointers)
1594
1595QT_BEGIN_NAMESPACE
1596
1597namespace QtSharedPointer {
1598 Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
1599}
1600
1601/*!
1602 \internal
1603*/
1604void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
1605{
1606 KnownPointers *const kp = knownPointers();
1607 if (!kp)
1608 return; // end-game: the application is being destroyed already
1609
1610 if (!ptr) {
1611 // nullptr is allowed to be tracked by more than one QSharedPointer, so we
1612 // need something else to put in our tracking structures
1613 ptr = d_ptr;
1614 }
1615
1616 QMutexLocker lock(&kp->mutex);
1617 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1618
1619 //qDebug("Adding d=%p value=%p", d_ptr, ptr);
1620
1621 const void *other_d_ptr = kp->dataPointers.value(ptr, nullptr);
1622 if (Q_UNLIKELY(other_d_ptr)) {
1623# ifdef BACKTRACE_SUPPORTED
1624 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1625# endif
1626 qFatal("QSharedPointer: internal self-check failed: pointer %p was already tracked "
1627 "by another QSharedPointer object %p", ptr, other_d_ptr);
1628 }
1629
1630 Data data;
1631 data.pointer = ptr;
1632# ifdef BACKTRACE_SUPPORTED
1633 data.backtrace = saveBacktrace();
1634# endif
1635
1636 kp->dPointers.insert(d_ptr, data);
1637 kp->dataPointers.insert(ptr, d_ptr);
1638 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1639}
1640
1641/*!
1642 \internal
1643*/
1644void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
1645{
1646 KnownPointers *const kp = knownPointers();
1647 if (!kp)
1648 return; // end-game: the application is being destroyed already
1649
1650 QMutexLocker lock(&kp->mutex);
1651
1652 const auto it = kp->dPointers.constFind(d_ptr);
1653 if (Q_UNLIKELY(it == kp->dPointers.cend())) {
1654 qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
1655 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
1656 "in your code.", d_ptr);
1657 }
1658
1659 const auto it2 = kp->dataPointers.constFind(it->pointer);
1660 Q_ASSERT(it2 != kp->dataPointers.cend());
1661
1662 //qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
1663
1664 // remove entries
1665 kp->dataPointers.erase(it2);
1666 kp->dPointers.erase(it);
1667 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1668}
1669
1670/*!
1671 \internal
1672 Called by the QSharedPointer autotest
1673*/
1674void QtSharedPointer::internalSafetyCheckCleanCheck()
1675{
1676# ifdef QT_BUILD_INTERNAL
1677 KnownPointers *const kp = knownPointers();
1678 Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
1679
1680 if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
1681 qFatal("Internal consistency error: the number of pointers is not equal!");
1682
1683 if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
1684 qFatal("Pointer cleaning failed: %d entries remaining", int(kp->dPointers.size()));
1685# endif
1686}
1687
1688QT_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