1 // Copyright (c) 2011 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 under third_party_mods/chromium or at: 4 // http://src.chromium.org/svn/trunk/src/LICENSE 5 6 #ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_ 7 #define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_ 8 9 namespace webrtc { 10 11 // Extracted from Chromium's src/base/memory/ref_counted.h. 12 13 // 14 // A smart pointer class for reference counted objects. Use this class instead 15 // of calling AddRef and Release manually on a reference counted object to 16 // avoid common memory leaks caused by forgetting to Release an object 17 // reference. Sample usage: 18 // 19 // class MyFoo : public RefCounted<MyFoo> { 20 // ... 21 // }; 22 // 23 // void some_function() { 24 // scoped_refptr<MyFoo> foo = new MyFoo(); 25 // foo->Method(param); 26 // // |foo| is released when this function returns 27 // } 28 // 29 // void some_other_function() { 30 // scoped_refptr<MyFoo> foo = new MyFoo(); 31 // ... 32 // foo = NULL; // explicitly releases |foo| 33 // ... 34 // if (foo) 35 // foo->Method(param); 36 // } 37 // 38 // The above examples show how scoped_refptr<T> acts like a pointer to T. 39 // Given two scoped_refptr<T> classes, it is also possible to exchange 40 // references between the two objects, like so: 41 // 42 // { 43 // scoped_refptr<MyFoo> a = new MyFoo(); 44 // scoped_refptr<MyFoo> b; 45 // 46 // b.swap(a); 47 // // now, |b| references the MyFoo object, and |a| references NULL. 48 // } 49 // 50 // To make both |a| and |b| in the above example reference the same MyFoo 51 // object, simply use the assignment operator: 52 // 53 // { 54 // scoped_refptr<MyFoo> a = new MyFoo(); 55 // scoped_refptr<MyFoo> b; 56 // 57 // b = a; 58 // // now, |a| and |b| each own a reference to the same MyFoo object. 59 // } 60 // 61 template <class T> 62 class scoped_refptr { 63 public: scoped_refptr()64 scoped_refptr() : ptr_(NULL) { 65 } 66 scoped_refptr(T * p)67 scoped_refptr(T* p) : ptr_(p) { 68 if (ptr_) 69 ptr_->AddRef(); 70 } 71 scoped_refptr(const scoped_refptr<T> & r)72 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 73 if (ptr_) 74 ptr_->AddRef(); 75 } 76 77 template <typename U> scoped_refptr(const scoped_refptr<U> & r)78 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 79 if (ptr_) 80 ptr_->AddRef(); 81 } 82 ~scoped_refptr()83 ~scoped_refptr() { 84 if (ptr_) 85 ptr_->Release(); 86 } 87 get()88 T* get() const { return ptr_; } 89 operator T*() const { return ptr_; } 90 T* operator->() const { return ptr_; } 91 92 // Release a pointer. 93 // The return value is the current pointer held by this object. 94 // If this object holds a NULL pointer, the return value is NULL. 95 // After this operation, this object will hold a NULL pointer, 96 // and will not own the object any more. release()97 T* release() { 98 T* retVal = ptr_; 99 ptr_ = NULL; 100 return retVal; 101 } 102 103 scoped_refptr<T>& operator=(T* p) { 104 // AddRef first so that self assignment should work 105 if (p) 106 p->AddRef(); 107 if (ptr_ ) 108 ptr_->Release(); 109 ptr_ = p; 110 return *this; 111 } 112 113 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 114 return *this = r.ptr_; 115 } 116 117 template <typename U> 118 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 119 return *this = r.get(); 120 } 121 swap(T ** pp)122 void swap(T** pp) { 123 T* p = ptr_; 124 ptr_ = *pp; 125 *pp = p; 126 } 127 swap(scoped_refptr<T> & r)128 void swap(scoped_refptr<T>& r) { 129 swap(&r.ptr_); 130 } 131 132 protected: 133 T* ptr_; 134 }; 135 } // namespace webrtc 136 137 #endif // SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_ 138