summaryrefslogtreecommitdiff
path: root/helpers
diff options
context:
space:
mode:
authorJose Fonseca <jfonseca@vmware.com>2015-07-24 12:50:30 +0100
committerJose Fonseca <jfonseca@vmware.com>2015-07-24 21:15:45 +0100
commitf7c9fa46c1f764c404e551d9da7121ecdcddf3c7 (patch)
treeb69e75726a4edce187f5203a8843e75a9dc8b452 /helpers
parent89ebe5e79c6cae483d2429f83cb0eab78821da2d (diff)
helpers: Improve com_ptr.
Diffstat (limited to 'helpers')
-rw-r--r--helpers/com_ptr.hpp61
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;
};