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