diff options
author | Jose Fonseca <jfonseca@vmware.com> | 2015-07-24 12:50:30 +0100 |
---|---|---|
committer | Jose Fonseca <jfonseca@vmware.com> | 2015-07-24 21:15:45 +0100 |
commit | f7c9fa46c1f764c404e551d9da7121ecdcddf3c7 (patch) | |
tree | b69e75726a4edce187f5203a8843e75a9dc8b452 /helpers | |
parent | 89ebe5e79c6cae483d2429f83cb0eab78821da2d (diff) |
helpers: Improve com_ptr.
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/com_ptr.hpp | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/helpers/com_ptr.hpp b/helpers/com_ptr.hpp index e822b6e8..d85483df 100644 --- a/helpers/com_ptr.hpp +++ b/helpers/com_ptr.hpp @@ -28,31 +28,45 @@ #include <assert.h> +#include <windows.h> + /** * Simple smart pointer template for COM interfaces. + * + * - https://msdn.microsoft.com/en-us/magazine/dn904668.aspx + * - https://msdn.microsoft.com/en-us/library/417w8b3b.aspx + * - https://msdn.microsoft.com/en-us/library/ezzw7k98.aspx */ -template< class T > +template< typename T > class com_ptr { private: T *p; public: - com_ptr(void) { - p = NULL; + com_ptr(void) : + p(nullptr) + { + } + + com_ptr(T *_p) : + p(_p) + { } ~com_ptr() { - if (p) { - p->Release(); + T *temp = p; + p = nullptr; + if (temp) { + temp->Release(); } } // Used when initializing T ** operator & () { - assert(p == NULL); + assert(p == nullptr); return &p; } @@ -61,26 +75,37 @@ public: return p; } + struct no_ref_count : public T + { + private: + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + }; + // Methods - T * + no_ref_count * operator -> () const { - return p; + assert(p != nullptr); + return static_cast< no_ref_count *>(p); } - T * + com_ptr & operator = (T *q) { - if (p) { - p->Release(); + if (p != q) { + T *temp = p; + p = q; + if (temp) { + temp->Release(); + } + if (q) { + q->AddRef(); + } } - if (q) { - q->AddRef(); - } - return p = q; + return *this; } -private: - com_ptr(const com_ptr &); - com_ptr & operator= (const com_ptr &); + com_ptr(const com_ptr &) = delete; + com_ptr & operator= (const com_ptr &) = delete; }; |