tc_autoptr.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #ifndef __TC_AUTOPTR_H
  17. #define __TC_AUTOPTR_H
  18. #include "util/tc_ex.h"
  19. #include "util/tc_platform.h"
  20. #include <atomic>
  21. #include <typeinfo>
  22. namespace tars
  23. {
  24. /**
  25. * @brief 空指针异常
  26. */
  27. struct TC_AutoPtrNull_Exception : public TC_Exception
  28. {
  29. TC_AutoPtrNull_Exception(const string &buffer) : TC_Exception(buffer){};
  30. ~TC_AutoPtrNull_Exception() {};
  31. };
  32. /**
  33. * @brief 智能指针基类.
  34. *
  35. * 所有需要智能指针支持的类都需要从该对象继承,
  36. *
  37. */
  38. class UTIL_DLL_API TC_HandleBase
  39. {
  40. public:
  41. /**
  42. * @brief 复制.
  43. *
  44. * @return TC_HandleBase&
  45. */
  46. TC_HandleBase& operator=(const TC_HandleBase&)
  47. {
  48. return *this;
  49. }
  50. /**
  51. * @brief 增加计数
  52. */
  53. void incRef() { ++_atomic; }
  54. /**
  55. * @brief 减少计数, 当计数==0时, 且需要删除数据时, 释放对象
  56. */
  57. void decRef()
  58. {
  59. if((--_atomic) == 0 && !_bNoDelete)
  60. {
  61. _bNoDelete = true;
  62. delete this;
  63. }
  64. }
  65. /**
  66. * @brief 获取计数.
  67. *
  68. * @return int 计数值
  69. */
  70. int getRef() const { return _atomic; }
  71. /**
  72. * @brief 设置不自动释放.
  73. *
  74. * @param b 是否自动删除,true or false
  75. */
  76. void setNoDelete(bool b) { _bNoDelete = b; }
  77. protected:
  78. /**
  79. * @brief 构造函数
  80. */
  81. TC_HandleBase() : _atomic(0), _bNoDelete(false)
  82. {
  83. }
  84. /**
  85. * @brief 拷贝构造
  86. */
  87. TC_HandleBase(const TC_HandleBase&) : _atomic(0), _bNoDelete(false)
  88. {
  89. }
  90. /**
  91. * @brief 析够
  92. */
  93. virtual ~TC_HandleBase()
  94. {
  95. }
  96. protected:
  97. /**
  98. * 计数
  99. */
  100. std::atomic<int> _atomic;
  101. /**
  102. * 是否自动删除
  103. */
  104. bool _bNoDelete;
  105. };
  106. /**
  107. * @brief 智能指针模板类.
  108. *
  109. * 可以放在容器中,且线程安全的智能指针.
  110. *
  111. * 通过它定义智能指针,该智能指针通过引用计数实现,
  112. *
  113. * 可以放在容器中传递.
  114. *
  115. * template<typename T> T必须继承于TC_HandleBase
  116. */
  117. template<typename T>
  118. class TC_AutoPtr
  119. {
  120. public:
  121. /**
  122. * 元素类型
  123. */
  124. typedef T element_type;
  125. /**
  126. * @brief 用原生指针初始化, 计数+1.
  127. *
  128. * @param p
  129. */
  130. TC_AutoPtr(T* p = 0)
  131. {
  132. _ptr = p;
  133. if(_ptr)
  134. {
  135. _ptr->incRef();
  136. }
  137. }
  138. /**
  139. * @brief 用其他智能指针r的原生指针初始化, 计数+1.
  140. *
  141. * @param Y
  142. * @param r
  143. */
  144. template<typename Y>
  145. TC_AutoPtr(const TC_AutoPtr<Y>& r)
  146. {
  147. _ptr = r._ptr;
  148. if(_ptr)
  149. {
  150. _ptr->incRef();
  151. }
  152. }
  153. /**
  154. * @brief 拷贝构造, 计数+1.
  155. *
  156. * @param r
  157. */
  158. TC_AutoPtr(const TC_AutoPtr& r)
  159. {
  160. _ptr = r._ptr;
  161. if(_ptr)
  162. {
  163. _ptr->incRef();
  164. }
  165. }
  166. /**
  167. * @brief 析构
  168. */
  169. ~TC_AutoPtr()
  170. {
  171. if(_ptr)
  172. {
  173. _ptr->decRef();
  174. }
  175. }
  176. /**
  177. * @brief 赋值, 普通指针.
  178. *
  179. * @param p
  180. * @return TC_AutoPtr&
  181. */
  182. TC_AutoPtr& operator=(T* p)
  183. {
  184. if(_ptr != p)
  185. {
  186. if(p)
  187. {
  188. p->incRef();
  189. }
  190. T* ptr = _ptr;
  191. _ptr = p;
  192. if(ptr)
  193. {
  194. ptr->decRef();
  195. }
  196. }
  197. return *this;
  198. }
  199. /**
  200. * @brief 赋值, 其他类型智能指针.
  201. *
  202. * @param Y
  203. * @param r
  204. * @return TC_AutoPtr&
  205. */
  206. template<typename Y>
  207. TC_AutoPtr& operator=(const TC_AutoPtr<Y>& r)
  208. {
  209. if(_ptr != r._ptr)
  210. {
  211. if(r._ptr)
  212. {
  213. r._ptr->incRef();
  214. }
  215. T* ptr = _ptr;
  216. _ptr = r._ptr;
  217. if(ptr)
  218. {
  219. ptr->decRef();
  220. }
  221. }
  222. return *this;
  223. }
  224. /**
  225. * @brief 赋值, 该类型其他执政指针.
  226. *
  227. * @param r
  228. * @return TC_AutoPtr&
  229. */
  230. TC_AutoPtr& operator=(const TC_AutoPtr& r)
  231. {
  232. if(_ptr != r._ptr)
  233. {
  234. if(r._ptr)
  235. {
  236. r._ptr->incRef();
  237. }
  238. T* ptr = _ptr;
  239. _ptr = r._ptr;
  240. if(ptr)
  241. {
  242. ptr->decRef();
  243. }
  244. }
  245. return *this;
  246. }
  247. /**
  248. * @brief 将其他类型的智能指针换成当前类型的智能指针.
  249. *
  250. * @param Y
  251. * @param r
  252. * @return TC_AutoPtr
  253. */
  254. template<class Y>
  255. static TC_AutoPtr dynamicCast(const TC_AutoPtr<Y>& r)
  256. {
  257. return TC_AutoPtr(dynamic_cast<T*>(r._ptr));
  258. }
  259. /**
  260. * @brief 将其他原生类型的指针转换成当前类型的智能指针.
  261. *
  262. * @param Y
  263. * @param p
  264. * @return TC_AutoPtr
  265. */
  266. template<class Y>
  267. static TC_AutoPtr dynamicCast(Y* p)
  268. {
  269. return TC_AutoPtr(dynamic_cast<T*>(p));
  270. }
  271. /**
  272. * @brief 获取原生指针.
  273. *
  274. * @return T*
  275. */
  276. T* get() const
  277. {
  278. return _ptr;
  279. }
  280. /**
  281. * @brief 调用.
  282. *
  283. * @return T*
  284. */
  285. T* operator->() const
  286. {
  287. if(!_ptr)
  288. {
  289. throwNullHandleException();
  290. }
  291. return _ptr;
  292. }
  293. /**
  294. * @brief 引用.
  295. *
  296. * @return T&
  297. */
  298. T& operator*() const
  299. {
  300. if(!_ptr)
  301. {
  302. throwNullHandleException();
  303. }
  304. return *_ptr;
  305. }
  306. /**
  307. * @brief 是否有效.
  308. *
  309. * @return bool
  310. */
  311. operator bool() const
  312. {
  313. return _ptr ? true : false;
  314. }
  315. /**
  316. * @brief 交换指针.
  317. *
  318. * @param other
  319. */
  320. void swap(TC_AutoPtr& other)
  321. {
  322. std::swap(_ptr, other._ptr);
  323. }
  324. protected:
  325. /**
  326. * @brief 抛出异常
  327. */
  328. void throwNullHandleException() const;
  329. public:
  330. T* _ptr;
  331. };
  332. /**
  333. * @brief 抛出异常.
  334. *
  335. * @param T
  336. * @param file
  337. * @param line
  338. */
  339. template<typename T> inline void
  340. TC_AutoPtr<T>::throwNullHandleException() const
  341. {
  342. throw TC_AutoPtrNull_Exception("autoptr null handle error![" + string(typeid(T).name()) +"]");
  343. }
  344. /**
  345. * @brief ==判断.
  346. *
  347. * @param T
  348. * @param U
  349. * @param lhs
  350. * @param rhs
  351. *
  352. * @return bool
  353. */
  354. template<typename T, typename U>
  355. inline bool operator==(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
  356. {
  357. T* l = lhs.get();
  358. U* r = rhs.get();
  359. // 改为直接比较指针,而不是比较值
  360. return (l == r);
  361. }
  362. /**
  363. * @brief 不等于判断.
  364. *
  365. * @param T
  366. * @param U
  367. * @param lhs
  368. * @param rhs
  369. *
  370. * @return bool
  371. */
  372. template<typename T, typename U>
  373. inline bool operator!=(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
  374. {
  375. T* l = lhs.get();
  376. U* r = rhs.get();
  377. // 改为直接比较指针,而不是比较值
  378. return (l != r);
  379. }
  380. /**
  381. * @brief 小于判断, 用于放在map等容器中.
  382. *
  383. * @param T
  384. * @param U
  385. * @param lhs
  386. * @param rhs
  387. *
  388. * @return bool
  389. */
  390. template<typename T, typename U>
  391. inline bool operator<(const TC_AutoPtr<T>& lhs, const TC_AutoPtr<U>& rhs)
  392. {
  393. T* l = lhs.get();
  394. U* r = rhs.get();
  395. if(l && r)
  396. {
  397. //return *l < *r;
  398. // 改为直接比较指针,而不是比较值
  399. return (l < r);
  400. }
  401. else
  402. {
  403. return !l && r;
  404. }
  405. }
  406. }
  407. #endif