1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | // This class acts a smart pointer which calls the Release method on any object |
6 | // you place in it when the ReleaseHolder class falls out of scope. You may use it |
7 | // just like you would a standard pointer to a COM object (including if (foo), |
8 | // if (!foo), if (foo == 0), etc) except for two caveats: |
9 | // 1. This class never calls AddRef and it always calls Release when it |
10 | // goes out of scope. |
11 | // 2. You should never use & to try to get a pointer to a pointer unless |
12 | // you call Release first, or you will leak whatever this object contains |
13 | // prior to updating its internal pointer. |
14 | template<class T> |
15 | class ReleaseHolder |
16 | { |
17 | public: |
18 | ReleaseHolder() |
19 | : m_ptr(NULL) |
20 | {} |
21 | |
22 | ReleaseHolder(T* ptr) |
23 | : m_ptr(ptr) |
24 | {} |
25 | |
26 | ~ReleaseHolder() |
27 | { |
28 | Release(); |
29 | } |
30 | |
31 | void operator=(T *ptr) |
32 | { |
33 | Release(); |
34 | |
35 | m_ptr = ptr; |
36 | } |
37 | |
38 | T* operator->() |
39 | { |
40 | return m_ptr; |
41 | } |
42 | |
43 | operator T*() |
44 | { |
45 | return m_ptr; |
46 | } |
47 | |
48 | T** operator&() |
49 | { |
50 | return &m_ptr; |
51 | } |
52 | |
53 | T* GetPtr() const |
54 | { |
55 | return m_ptr; |
56 | } |
57 | |
58 | T* Detach() |
59 | { |
60 | T* pT = m_ptr; |
61 | m_ptr = NULL; |
62 | return pT; |
63 | } |
64 | |
65 | void Release() |
66 | { |
67 | if (m_ptr != NULL) |
68 | { |
69 | m_ptr->Release(); |
70 | m_ptr = NULL; |
71 | } |
72 | } |
73 | |
74 | private: |
75 | T* m_ptr; |
76 | }; |
77 | |
78 | |