| 237 | */ |
| 238 | template <class T> |
| 239 | class Ref |
| 240 | { |
| 241 | T* m_obj; |
| 242 | #ifdef BN_REF_COUNT_DEBUG |
| 243 | void* m_assignmentTrace = nullptr; |
| 244 | #endif |
| 245 | |
| 246 | public: |
| 247 | Ref() : m_obj(nullptr) {} |
| 248 | |
| 249 | Ref(T* obj) : m_obj(obj) |
| 250 | { |
| 251 | if (m_obj) |
| 252 | { |
| 253 | m_obj->AddRef(); |
| 254 | #ifdef BN_REF_COUNT_DEBUG |
| 255 | m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); |
| 256 | #endif |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | Ref(const Ref<T>& obj) : m_obj(obj.m_obj) |
| 261 | { |
| 262 | if (m_obj) |
| 263 | { |
| 264 | m_obj->AddRef(); |
| 265 | #ifdef BN_REF_COUNT_DEBUG |
| 266 | m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); |
| 267 | #endif |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | Ref(Ref<T>&& other) : m_obj(other.m_obj) |
| 272 | { |
| 273 | other.m_obj = 0; |
| 274 | #ifdef BN_REF_COUNT_DEBUG |
| 275 | m_assignmentTrace = other.m_assignmentTrace; |
| 276 | #endif |
| 277 | } |
| 278 | |
| 279 | ~Ref() |
| 280 | { |
| 281 | if (m_obj) |
| 282 | { |
| 283 | m_obj->Release(); |
| 284 | #ifdef BN_REF_COUNT_DEBUG |
| 285 | BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); |
| 286 | #endif |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | Ref<T>& operator=(const Ref<T>& obj) |
| 291 | { |
| 292 | #ifdef BN_REF_COUNT_DEBUG |
| 293 | if (m_obj) |
| 294 | BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); |
| 295 | if (obj.m_obj) |
| 296 | m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); |