scoped_refptr.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. // Originally these classes are from Chromium.
  11. // http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup
  12. //
  13. // A smart pointer class for reference counted objects. Use this class instead
  14. // of calling AddRef and Release manually on a reference counted object to
  15. // avoid common memory leaks caused by forgetting to Release an object
  16. // reference. Sample usage:
  17. //
  18. // class MyFoo : public RefCounted<MyFoo> {
  19. // ...
  20. // };
  21. //
  22. // void some_function() {
  23. // scoped_refptr<MyFoo> foo = new MyFoo();
  24. // foo->Method(param);
  25. // // |foo| is released when this function returns
  26. // }
  27. //
  28. // void some_other_function() {
  29. // scoped_refptr<MyFoo> foo = new MyFoo();
  30. // ...
  31. // foo = nullptr; // explicitly releases |foo|
  32. // ...
  33. // if (foo)
  34. // foo->Method(param);
  35. // }
  36. //
  37. // The above examples show how scoped_refptr<T> acts like a pointer to T.
  38. // Given two scoped_refptr<T> classes, it is also possible to exchange
  39. // references between the two objects, like so:
  40. //
  41. // {
  42. // scoped_refptr<MyFoo> a = new MyFoo();
  43. // scoped_refptr<MyFoo> b;
  44. //
  45. // b.swap(a);
  46. // // now, |b| references the MyFoo object, and |a| references null.
  47. // }
  48. //
  49. // To make both |a| and |b| in the above example reference the same MyFoo
  50. // object, simply use the assignment operator:
  51. //
  52. // {
  53. // scoped_refptr<MyFoo> a = new MyFoo();
  54. // scoped_refptr<MyFoo> b;
  55. //
  56. // b = a;
  57. // // now, |a| and |b| each own a reference to the same MyFoo object.
  58. // }
  59. //
  60. #ifndef API_SCOPED_REFPTR_H_
  61. #define API_SCOPED_REFPTR_H_
  62. #include <memory>
  63. #include <utility>
  64. namespace rtc {
  65. template <class T>
  66. class scoped_refptr {
  67. public:
  68. typedef T element_type;
  69. scoped_refptr() : ptr_(nullptr) {}
  70. scoped_refptr(T* p) : ptr_(p) { // NOLINT(runtime/explicit)
  71. if (ptr_)
  72. ptr_->AddRef();
  73. }
  74. scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
  75. if (ptr_)
  76. ptr_->AddRef();
  77. }
  78. template <typename U>
  79. scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
  80. if (ptr_)
  81. ptr_->AddRef();
  82. }
  83. // Move constructors.
  84. scoped_refptr(scoped_refptr<T>&& r) noexcept : ptr_(r.release()) {}
  85. template <typename U>
  86. scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.release()) {}
  87. ~scoped_refptr() {
  88. if (ptr_)
  89. ptr_->Release();
  90. }
  91. T* get() const { return ptr_; }
  92. operator T*() const { return ptr_; }
  93. T* operator->() const { return ptr_; }
  94. // Returns the (possibly null) raw pointer, and makes the scoped_refptr hold a
  95. // null pointer, all without touching the reference count of the underlying
  96. // pointed-to object. The object is still reference counted, and the caller of
  97. // release() is now the proud owner of one reference, so it is responsible for
  98. // calling Release() once on the object when no longer using it.
  99. T* release() {
  100. T* retVal = ptr_;
  101. ptr_ = nullptr;
  102. return retVal;
  103. }
  104. scoped_refptr<T>& operator=(T* p) {
  105. // AddRef first so that self assignment should work
  106. if (p)
  107. p->AddRef();
  108. if (ptr_)
  109. ptr_->Release();
  110. ptr_ = p;
  111. return *this;
  112. }
  113. scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
  114. return *this = r.ptr_;
  115. }
  116. template <typename U>
  117. scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
  118. return *this = r.get();
  119. }
  120. scoped_refptr<T>& operator=(scoped_refptr<T>&& r) noexcept {
  121. scoped_refptr<T>(std::move(r)).swap(*this);
  122. return *this;
  123. }
  124. template <typename U>
  125. scoped_refptr<T>& operator=(scoped_refptr<U>&& r) noexcept {
  126. scoped_refptr<T>(std::move(r)).swap(*this);
  127. return *this;
  128. }
  129. void swap(T** pp) noexcept {
  130. T* p = ptr_;
  131. ptr_ = *pp;
  132. *pp = p;
  133. }
  134. void swap(scoped_refptr<T>& r) noexcept { swap(&r.ptr_); }
  135. protected:
  136. T* ptr_;
  137. };
  138. } // namespace rtc
  139. #endif // API_SCOPED_REFPTR_H_