1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Weak pointers help in cases where you have many objects referring back to a
6 // shared object and you wish for the lifetime of the shared object to not be
7 // bound to the lifetime of the referrers. In other words, this is useful when
8 // reference counting is not a good fit.
10 // A common alternative to weak pointers is to have the shared object hold a
11 // list of all referrers, and then when the shared object is destroyed, it
12 // calls a method on the referrers to tell them to drop their references. This
13 // approach also requires the referrers to tell the shared object when they get
14 // destroyed so that the shared object can remove the referrer from its list of
15 // referrers. Such a solution works, but it is a bit complex.
19 // class Controller : public SupportsWeakPtr<Controller> {
21 // void SpawnWorker() { Worker::StartNew(AsWeakPtr()); }
22 // void WorkComplete(const Result& result) { ... }
27 // static void StartNew(const WeakPtr<Controller>& controller) {
28 // Worker* worker = new Worker(controller);
29 // // Kick off asynchronous processing...
32 // Worker(const WeakPtr<Controller>& controller)
33 // : controller_(controller) {}
34 // void DidCompleteAsynchronousProcessing(const Result& result) {
36 // controller_->WorkComplete(result);
38 // WeakPtr<Controller> controller_;
41 // Given the above classes, a consumer may allocate a Controller object, call
42 // SpawnWorker several times, and then destroy the Controller object before all
43 // of the workers have completed. Because the Worker class only holds a weak
44 // pointer to the Controller, we don't have to worry about the Worker
45 // dereferencing the Controller back pointer after the Controller has been
48 // WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr
49 // instance on thread where it was created.
51 #ifndef BASE_WEAK_PTR_H_
52 #define BASE_WEAK_PTR_H_
55 #include "base/logging.h"
56 #include "base/ref_counted.h"
57 #include "base/threading/non_thread_safe.h"
62 // These classes are part of the WeakPtr implementation.
63 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
67 class Flag
: public RefCounted
<Flag
>, public base::NonThreadSafe
{
74 void Invalidate() { handle_
= NULL
; }
75 bool is_valid() const { return handle_
!= NULL
; }
77 void DetachFromThread() { base::NonThreadSafe::DetachFromThread(); }
84 WeakReference(Flag
* flag
);
87 bool is_valid() const;
90 scoped_refptr
<Flag
> flag_
;
93 class WeakReferenceOwner
{
96 ~WeakReferenceOwner();
98 WeakReference
GetRef() const;
100 bool HasRefs() const {
101 return flag_
!= NULL
;
106 // Indicates that this object will be used on another thread from now on.
107 void DetachFromThread() {
108 if (flag_
) flag_
->DetachFromThread();
112 mutable WeakReference::Flag
* flag_
;
115 // This class simplifies the implementation of WeakPtr's type conversion
116 // constructor by avoiding the need for a public accessor for ref_. A
117 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
118 // base class gives us a way to access ref_ in a protected fashion.
125 WeakPtrBase(const WeakReference
& ref
);
130 } // namespace internal
132 template <typename T
> class SupportsWeakPtr
;
133 template <typename T
> class WeakPtrFactory
;
135 // The WeakPtr class holds a weak reference to |T*|.
137 // This class is designed to be used like a normal pointer. You should always
138 // null-test an object of this class before using it or invoking a method that
139 // may result in the underlying object being destroyed.
143 // class Foo { ... };
148 template <typename T
>
149 class WeakPtr
: public internal::WeakPtrBase
{
151 WeakPtr() : ptr_(NULL
) {
154 // Allow conversion from U to T provided U "is a" T.
155 template <typename U
>
156 WeakPtr(const WeakPtr
<U
>& other
) : WeakPtrBase(other
), ptr_(other
.get()) {
159 T
* get() const { return ref_
.is_valid() ? ptr_
: NULL
; }
160 operator T
*() const { return get(); }
162 T
* operator*() const {
163 DCHECK(get() != NULL
);
166 T
* operator->() const {
167 DCHECK(get() != NULL
);
172 ref_
= internal::WeakReference();
177 friend class SupportsWeakPtr
<T
>;
178 friend class WeakPtrFactory
<T
>;
180 WeakPtr(const internal::WeakReference
& ref
, T
* ptr
)
181 : WeakPtrBase(ref
), ptr_(ptr
) {
184 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
185 // value is undefined (as opposed to NULL).
189 // A class may extend from SupportsWeakPtr to expose weak pointers to itself.
190 // This is useful in cases where you want others to be able to get a weak
191 // pointer to your class. It also has the property that you don't need to
192 // initialize it from your constructor.
194 class SupportsWeakPtr
{
198 WeakPtr
<T
> AsWeakPtr() {
199 return WeakPtr
<T
>(weak_reference_owner_
.GetRef(), static_cast<T
*>(this));
202 // Indicates that this object will be used on another thread from now on.
203 void DetachFromThread() {
204 weak_reference_owner_
.DetachFromThread();
208 internal::WeakReferenceOwner weak_reference_owner_
;
209 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr
);
212 // A class may alternatively be composed of a WeakPtrFactory and thereby
213 // control how it exposes weak pointers to itself. This is helpful if you only
214 // need weak pointers within the implementation of a class. This class is also
215 // useful when working with primitive types. For example, you could have a
216 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
218 class WeakPtrFactory
{
220 explicit WeakPtrFactory(T
* ptr
) : ptr_(ptr
) {
223 WeakPtr
<T
> GetWeakPtr() {
224 return WeakPtr
<T
>(weak_reference_owner_
.GetRef(), ptr_
);
227 // Call this method to invalidate all existing weak pointers.
228 void InvalidateWeakPtrs() {
229 weak_reference_owner_
.Invalidate();
232 // Call this method to determine if any weak pointers exist.
233 bool HasWeakPtrs() const {
234 return weak_reference_owner_
.HasRefs();
238 internal::WeakReferenceOwner weak_reference_owner_
;
240 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory
);
245 #endif // BASE_WEAK_PTR_H_