base_refcounted.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright (c) 2012 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.
  4. #ifndef BASE_REFCOUNTED_H_
  5. #define BASE_REFCOUNTED_H_
  6. namespace base {
  7. template <typename T>
  8. class RefCounted {
  9. public:
  10. RefCounted() {}
  11. protected:
  12. ~RefCounted() {}
  13. };
  14. template <typename T>
  15. class RefCountedThreadSafe {
  16. public:
  17. RefCountedThreadSafe() {}
  18. protected:
  19. ~RefCountedThreadSafe() {}
  20. };
  21. } // namespace base
  22. // Ignore classes whose inheritance tree ends in WebKit's RefCounted base
  23. // class. Though prone to error, this pattern is very prevalent in WebKit
  24. // code, so do not issue any warnings.
  25. namespace WebKit {
  26. template <typename T>
  27. class RefCounted {
  28. public:
  29. RefCounted() {}
  30. ~RefCounted() {}
  31. };
  32. } // namespace WebKit
  33. // Unsafe; should error.
  34. class PublicRefCountedDtorInHeader
  35. : public base::RefCounted<PublicRefCountedDtorInHeader> {
  36. public:
  37. PublicRefCountedDtorInHeader() {}
  38. ~PublicRefCountedDtorInHeader() {}
  39. private:
  40. friend class base::RefCounted<PublicRefCountedDtorInHeader>;
  41. };
  42. // Unsafe; should error.
  43. class PublicRefCountedThreadSafeDtorInHeader
  44. : public base::RefCountedThreadSafe<
  45. PublicRefCountedThreadSafeDtorInHeader> {
  46. public:
  47. PublicRefCountedThreadSafeDtorInHeader() {}
  48. ~PublicRefCountedThreadSafeDtorInHeader() {}
  49. private:
  50. friend class base::RefCountedThreadSafe<
  51. PublicRefCountedThreadSafeDtorInHeader>;
  52. };
  53. // Unsafe; should error.
  54. class ProtectedRefCountedDtorInHeader
  55. : public base::RefCounted<ProtectedRefCountedDtorInHeader> {
  56. public:
  57. ProtectedRefCountedDtorInHeader() {}
  58. protected:
  59. ~ProtectedRefCountedDtorInHeader() {}
  60. private:
  61. friend class base::RefCounted<ProtectedRefCountedDtorInHeader>;
  62. };
  63. // Safe; should not have errors
  64. class ProtectedRefCountedVirtualDtorInHeader
  65. : public base::RefCounted<ProtectedRefCountedVirtualDtorInHeader> {
  66. public:
  67. ProtectedRefCountedVirtualDtorInHeader() {}
  68. protected:
  69. virtual ~ProtectedRefCountedVirtualDtorInHeader() {}
  70. private:
  71. friend class base::RefCounted<ProtectedRefCountedVirtualDtorInHeader>;
  72. };
  73. // Safe; should not have errors.
  74. class PrivateRefCountedDtorInHeader
  75. : public base::RefCounted<PrivateRefCountedDtorInHeader> {
  76. public:
  77. PrivateRefCountedDtorInHeader() {}
  78. private:
  79. ~PrivateRefCountedDtorInHeader() {}
  80. friend class base::RefCounted<PrivateRefCountedDtorInHeader>;
  81. };
  82. // Unsafe; A grandchild class ends up exposing their parent and grandparent's
  83. // destructors.
  84. class DerivedProtectedToPublicInHeader
  85. : public ProtectedRefCountedVirtualDtorInHeader {
  86. public:
  87. DerivedProtectedToPublicInHeader() {}
  88. ~DerivedProtectedToPublicInHeader() override {}
  89. };
  90. // Unsafe; A grandchild ends up implicitly exposing their parent and
  91. // grantparent's destructors.
  92. class ImplicitDerivedProtectedToPublicInHeader
  93. : public ProtectedRefCountedVirtualDtorInHeader {
  94. public:
  95. ImplicitDerivedProtectedToPublicInHeader() {}
  96. };
  97. // Unsafe-but-ignored; should not have errors.
  98. class WebKitPublicDtorInHeader
  99. : public WebKit::RefCounted<WebKitPublicDtorInHeader> {
  100. public:
  101. WebKitPublicDtorInHeader() {}
  102. ~WebKitPublicDtorInHeader() {}
  103. };
  104. // Unsafe-but-ignored; should not have errors.
  105. class WebKitDerivedPublicDtorInHeader
  106. : public WebKitPublicDtorInHeader {
  107. public:
  108. WebKitDerivedPublicDtorInHeader() {}
  109. ~WebKitDerivedPublicDtorInHeader() {}
  110. };
  111. class APublicInterface {
  112. public:
  113. virtual ~APublicInterface() {}
  114. virtual void DoFoo() = 0;
  115. };
  116. // Unsafe. "ImplementsAPublicInterface* foo" can be deleted via
  117. // "delete (APublicInterface*)foo;".
  118. class ImplementsAPublicInterface
  119. : public APublicInterface,
  120. public base::RefCounted<ImplementsAPublicInterface> {
  121. public:
  122. void DoFoo() override {}
  123. protected:
  124. ~ImplementsAPublicInterface() override {}
  125. private:
  126. friend class base::RefCounted<ImplementsAPublicInterface>;
  127. };
  128. class AnImplicitInterface {
  129. public:
  130. virtual void DoBar() {}
  131. };
  132. // Unsafe.
  133. class ImplementsAnImplicitInterface
  134. : public AnImplicitInterface,
  135. public base::RefCounted<ImplementsAnImplicitInterface> {
  136. public:
  137. void DoBar() override {}
  138. private:
  139. friend class base::RefCounted<ImplementsAnImplicitInterface>;
  140. ~ImplementsAnImplicitInterface() {}
  141. };
  142. // Safe. Private inheritance does not expose the base destructor.
  143. class PrivatelyImplementsAPublicInterface
  144. : private APublicInterface,
  145. public base::RefCounted<PrivatelyImplementsAPublicInterface> {
  146. public:
  147. void DoFoo() override {}
  148. private:
  149. friend class base::RefCounted<PrivatelyImplementsAPublicInterface>;
  150. ~PrivatelyImplementsAPublicInterface() override {}
  151. };
  152. // Unsafe.
  153. class BaseInterface {
  154. public:
  155. virtual ~BaseInterface() {}
  156. virtual void DoFoo() {}
  157. };
  158. class DerivedInterface : public BaseInterface {
  159. protected:
  160. ~DerivedInterface() override {}
  161. };
  162. class SomeOtherInterface {
  163. public:
  164. virtual ~SomeOtherInterface() {}
  165. virtual void DoBar() {}
  166. };
  167. class RefcountedType : public base::RefCounted<RefcountedType> {
  168. protected:
  169. ~RefcountedType() {}
  170. private:
  171. friend class base::RefCounted<RefcountedType>;
  172. };
  173. class UnsafeInheritanceChain
  174. : public DerivedInterface,
  175. public SomeOtherInterface,
  176. public RefcountedType {
  177. public:
  178. // DerivedInterface
  179. void DoFoo() override {}
  180. // SomeOtherInterface
  181. void DoBar() override {}
  182. protected:
  183. ~UnsafeInheritanceChain() override {}
  184. };
  185. #endif // BASE_REFCOUNTED_H_