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.
14template<class T>
15class ReleaseHolder
16{
17public:
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
74private:
75 T* m_ptr;
76};
77
78