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