OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Weak pointers are pointers to an object that do not affect its lifetime, | 5 // Weak pointers are pointers to an object that do not affect its lifetime, |
6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its | 6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its |
7 // owner, at any time, most commonly when the object is about to be deleted. | 7 // owner, at any time, most commonly when the object is about to be deleted. |
8 | 8 |
9 // Weak pointers are useful when an object needs to be accessed safely by one | 9 // Weak pointers are useful when an object needs to be accessed safely by one |
10 // or more objects other than its owner, and those callers can cope with the | 10 // or more objects other than its owner, and those callers can cope with the |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 } | 268 } |
269 template <class T> | 269 template <class T> |
270 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { | 270 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
271 return weak_ptr.get() == nullptr; | 271 return weak_ptr.get() == nullptr; |
272 } | 272 } |
273 template <class T> | 273 template <class T> |
274 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { | 274 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
275 return weak_ptr == nullptr; | 275 return weak_ptr == nullptr; |
276 } | 276 } |
277 | 277 |
| 278 namespace internal { |
| 279 class BASE_EXPORT WeakPtrFactoryBase { |
| 280 protected: |
| 281 WeakPtrFactoryBase(uintptr_t ptr); |
| 282 ~WeakPtrFactoryBase(); |
| 283 internal::WeakReferenceOwner weak_reference_owner_; |
| 284 uintptr_t ptr_; |
| 285 }; |
| 286 } // namespace internal |
| 287 |
278 // A class may be composed of a WeakPtrFactory and thereby | 288 // A class may be composed of a WeakPtrFactory and thereby |
279 // control how it exposes weak pointers to itself. This is helpful if you only | 289 // control how it exposes weak pointers to itself. This is helpful if you only |
280 // need weak pointers within the implementation of a class. This class is also | 290 // need weak pointers within the implementation of a class. This class is also |
281 // useful when working with primitive types. For example, you could have a | 291 // useful when working with primitive types. For example, you could have a |
282 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. | 292 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
283 template <class T> | 293 template <class T> |
284 class WeakPtrFactory { | 294 class WeakPtrFactory : public internal::WeakPtrFactoryBase { |
285 public: | 295 public: |
286 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { | 296 explicit WeakPtrFactory(T* ptr) |
287 } | 297 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} |
288 | 298 |
289 ~WeakPtrFactory() { ptr_ = nullptr; } | 299 ~WeakPtrFactory() {} |
290 | 300 |
291 WeakPtr<T> GetWeakPtr() { | 301 WeakPtr<T> GetWeakPtr() { |
292 DCHECK(ptr_); | 302 DCHECK(ptr_); |
293 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); | 303 return WeakPtr<T>(weak_reference_owner_.GetRef(), |
| 304 reinterpret_cast<T*>(ptr_)); |
294 } | 305 } |
295 | 306 |
296 // Call this method to invalidate all existing weak pointers. | 307 // Call this method to invalidate all existing weak pointers. |
297 void InvalidateWeakPtrs() { | 308 void InvalidateWeakPtrs() { |
298 DCHECK(ptr_); | 309 DCHECK(ptr_); |
299 weak_reference_owner_.Invalidate(); | 310 weak_reference_owner_.Invalidate(); |
300 } | 311 } |
301 | 312 |
302 // Call this method to determine if any weak pointers exist. | 313 // Call this method to determine if any weak pointers exist. |
303 bool HasWeakPtrs() const { | 314 bool HasWeakPtrs() const { |
304 DCHECK(ptr_); | 315 DCHECK(ptr_); |
305 return weak_reference_owner_.HasRefs(); | 316 return weak_reference_owner_.HasRefs(); |
306 } | 317 } |
307 | 318 |
308 private: | 319 private: |
309 internal::WeakReferenceOwner weak_reference_owner_; | |
310 T* ptr_; | |
311 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); | 320 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
312 }; | 321 }; |
313 | 322 |
314 // A class may extend from SupportsWeakPtr to let others take weak pointers to | 323 // A class may extend from SupportsWeakPtr to let others take weak pointers to |
315 // it. This avoids the class itself implementing boilerplate to dispense weak | 324 // it. This avoids the class itself implementing boilerplate to dispense weak |
316 // pointers. However, since SupportsWeakPtr's destructor won't invalidate | 325 // pointers. However, since SupportsWeakPtr's destructor won't invalidate |
317 // weak pointers to the class until after the derived class' members have been | 326 // weak pointers to the class until after the derived class' members have been |
318 // destroyed, its use can lead to subtle use-after-destroy issues. | 327 // destroyed, its use can lead to subtle use-after-destroy issues. |
319 template <class T> | 328 template <class T> |
320 class SupportsWeakPtr : public internal::SupportsWeakPtrBase { | 329 class SupportsWeakPtr : public internal::SupportsWeakPtrBase { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 361 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
353 | 362 |
354 template <typename Derived> | 363 template <typename Derived> |
355 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 364 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
356 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 365 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
357 } | 366 } |
358 | 367 |
359 } // namespace base | 368 } // namespace base |
360 | 369 |
361 #endif // BASE_MEMORY_WEAK_PTR_H_ | 370 #endif // BASE_MEMORY_WEAK_PTR_H_ |
OLD | NEW |