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