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 9namespace 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// 61template <class T> 62class scoped_refptr { 63 public: 64 scoped_refptr() : ptr_(NULL) { 65 } 66 67 scoped_refptr(T* p) : ptr_(p) { 68 if (ptr_) 69 ptr_->AddRef(); 70 } 71 72 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 73 if (ptr_) 74 ptr_->AddRef(); 75 } 76 77 template <typename U> 78 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 79 if (ptr_) 80 ptr_->AddRef(); 81 } 82 83 ~scoped_refptr() { 84 if (ptr_) 85 ptr_->Release(); 86 } 87 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. 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 122 void swap(T** pp) { 123 T* p = ptr_; 124 ptr_ = *pp; 125 *pp = p; 126 } 127 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