CComPtr对外不抛异常!
2008-03-25 08:17
309 查看
CComPtr对外不抛异常!
只是简单地对组件接口进行封装--使用中可以省略AddRef,Release和QuryInterface的频繁使用.
仍然靠HRESULT返回错误信息。
template <class T>
class CComPtr : public CComPtrBase<T>
{
public:
CComPtr() throw()
{
}
CComPtr(int nNull) throw() :
CComPtrBase<T>(nNull)
{
}
/*
template <typename Q>
CComPtr(Q* lp)
{
if (lp != NULL)
lp->QueryInterface(__uuidof(Q), (void**)&p);
else
p = NULL;
}
template <>
*/
CComPtr(T* lp) throw() :
CComPtrBase<T>(lp)
{
}
CComPtr(const CComPtr<T>& lp) throw() :
CComPtrBase<T>(lp.p)
{
}
// template<>
/*
T* operator=(void* lp)
{
return (T*)AtlComPtrAssign((IUnknown**)&p, (T*)lp);
}
*/
/*
template <typename Q>
T* operator=(Q* lp)
{
return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T));
}
template <>
*/
T* operator=(T* lp) throw()
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
template <typename Q>
T* operator=(const CComPtr<Q>& lp) throw()
{
return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T)));
}
template <>
T* operator=(const CComPtr<T>& lp) throw()
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
};
//CComPtrBase provides the basis for all other smart pointers
//The other smartpointers add their own constructors and operators
template <class T>
class CComPtrBase
{
protected:
CComPtrBase() throw()
{
p = NULL;
}
CComPtrBase(int nNull) throw()
{
ATLASSERT(nNull == 0);
(void)nNull;
p = NULL;
}
CComPtrBase(T* lp) throw()
{
p = lp;
if (p != NULL)
p->AddRef();
}
public:
typedef T _PtrClass;
~CComPtrBase() throw()
{
if (p)
p->Release();
}
operator T*() const throw()
{
return p;
}
T& operator*() const throw()
{
ATLASSERT(p!=NULL);
return *p;
}
//The assert on operator& usually indicates a bug. If this is really
//what is needed, however, take the address of the p member explicitly.
T** operator&() throw()
{
ATLASSERT(p==NULL);
return &p;
}
_NoAddRefReleaseOnCComPtr<T>* operator->() const throw()
{
ATLASSERT(p!=NULL);
return (_NoAddRefReleaseOnCComPtr<T>*)p;
}
bool operator!() const throw()
{
return (p == NULL);
}
bool operator<(T* pT) const throw()
{
return p < pT;
}
bool operator==(T* pT) const throw()
{
return p == pT;
}
// Release the interface and set to NULL
void Release() throw()
{
T* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
// Compare two objects for equivalence
bool IsEqualObject(IUnknown* pOther) throw()
{
if (p == pOther)
return true;
if (p == NULL || pOther == NULL)
return false; // One is NULL the other is not
CComPtr<IUnknown> punk1;
CComPtr<IUnknown> punk2;
p->QueryInterface(__uuidof(IUnknown), (void**)&punk1);
pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2);
return punk1 == punk2;
}
// Attach to an existing interface (does not AddRef)
void Attach(T* p2) throw()
{
if (p)
p->Release();
p = p2;
}
// Detach the interface (does not Release)
T* Detach() throw()
{
T* pt = p;
p = NULL;
return pt;
}
HRESULT CopyTo(T** ppT) throw()
{
ATLASSERT(ppT != NULL);
if (ppT == NULL)
return E_POINTER;
*ppT = p;
if (p)
p->AddRef();
return S_OK;
}
HRESULT SetSite(IUnknown* punkParent) throw()
{
return AtlSetChildSite(p, punkParent);
}
HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw) throw()
{
return AtlAdvise(p, pUnk, iid, pdw);
}
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
ATLASSERT(p == NULL);
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
}
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
ATLASSERT(p == NULL);
if (SUCCEEDED(hr))
hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
return hr;
}
template <class Q>
HRESULT QueryInterface(Q** pp) const throw()
{
ATLASSERT(pp != NULL);
return p->QueryInterface(__uuidof(Q), (void**)pp);
}
T* p;
};
当CComPtr spA = spB 时, 发生了什么------释放原接口,增加新接口引用并赋值给原接口。
ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
{
if (lp != NULL)
lp->AddRef(); // 增加新接口的引用
if (*pp)
(*pp)->Release(); // 如果原来的接口存在,减少对其引用---其实就是释放原接口。
*pp = lp;
return lp;
}
ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
{
IUnknown* pTemp = *pp;
*pp = NULL;
if (lp != NULL)
lp->QueryInterface(riid, (void**)pp);
if (pTemp)
pTemp->Release();
return *pp;
}
只是简单地对组件接口进行封装--使用中可以省略AddRef,Release和QuryInterface的频繁使用.
仍然靠HRESULT返回错误信息。
template <class T>
class CComPtr : public CComPtrBase<T>
{
public:
CComPtr() throw()
{
}
CComPtr(int nNull) throw() :
CComPtrBase<T>(nNull)
{
}
/*
template <typename Q>
CComPtr(Q* lp)
{
if (lp != NULL)
lp->QueryInterface(__uuidof(Q), (void**)&p);
else
p = NULL;
}
template <>
*/
CComPtr(T* lp) throw() :
CComPtrBase<T>(lp)
{
}
CComPtr(const CComPtr<T>& lp) throw() :
CComPtrBase<T>(lp.p)
{
}
// template<>
/*
T* operator=(void* lp)
{
return (T*)AtlComPtrAssign((IUnknown**)&p, (T*)lp);
}
*/
/*
template <typename Q>
T* operator=(Q* lp)
{
return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T));
}
template <>
*/
T* operator=(T* lp) throw()
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
template <typename Q>
T* operator=(const CComPtr<Q>& lp) throw()
{
return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T)));
}
template <>
T* operator=(const CComPtr<T>& lp) throw()
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
};
//CComPtrBase provides the basis for all other smart pointers
//The other smartpointers add their own constructors and operators
template <class T>
class CComPtrBase
{
protected:
CComPtrBase() throw()
{
p = NULL;
}
CComPtrBase(int nNull) throw()
{
ATLASSERT(nNull == 0);
(void)nNull;
p = NULL;
}
CComPtrBase(T* lp) throw()
{
p = lp;
if (p != NULL)
p->AddRef();
}
public:
typedef T _PtrClass;
~CComPtrBase() throw()
{
if (p)
p->Release();
}
operator T*() const throw()
{
return p;
}
T& operator*() const throw()
{
ATLASSERT(p!=NULL);
return *p;
}
//The assert on operator& usually indicates a bug. If this is really
//what is needed, however, take the address of the p member explicitly.
T** operator&() throw()
{
ATLASSERT(p==NULL);
return &p;
}
_NoAddRefReleaseOnCComPtr<T>* operator->() const throw()
{
ATLASSERT(p!=NULL);
return (_NoAddRefReleaseOnCComPtr<T>*)p;
}
bool operator!() const throw()
{
return (p == NULL);
}
bool operator<(T* pT) const throw()
{
return p < pT;
}
bool operator==(T* pT) const throw()
{
return p == pT;
}
// Release the interface and set to NULL
void Release() throw()
{
T* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
// Compare two objects for equivalence
bool IsEqualObject(IUnknown* pOther) throw()
{
if (p == pOther)
return true;
if (p == NULL || pOther == NULL)
return false; // One is NULL the other is not
CComPtr<IUnknown> punk1;
CComPtr<IUnknown> punk2;
p->QueryInterface(__uuidof(IUnknown), (void**)&punk1);
pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2);
return punk1 == punk2;
}
// Attach to an existing interface (does not AddRef)
void Attach(T* p2) throw()
{
if (p)
p->Release();
p = p2;
}
// Detach the interface (does not Release)
T* Detach() throw()
{
T* pt = p;
p = NULL;
return pt;
}
HRESULT CopyTo(T** ppT) throw()
{
ATLASSERT(ppT != NULL);
if (ppT == NULL)
return E_POINTER;
*ppT = p;
if (p)
p->AddRef();
return S_OK;
}
HRESULT SetSite(IUnknown* punkParent) throw()
{
return AtlSetChildSite(p, punkParent);
}
HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw) throw()
{
return AtlAdvise(p, pUnk, iid, pdw);
}
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
ATLASSERT(p == NULL);
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
}
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
ATLASSERT(p == NULL);
if (SUCCEEDED(hr))
hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
return hr;
}
template <class Q>
HRESULT QueryInterface(Q** pp) const throw()
{
ATLASSERT(pp != NULL);
return p->QueryInterface(__uuidof(Q), (void**)pp);
}
T* p;
};
当CComPtr spA = spB 时, 发生了什么------释放原接口,增加新接口引用并赋值给原接口。
ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
{
if (lp != NULL)
lp->AddRef(); // 增加新接口的引用
if (*pp)
(*pp)->Release(); // 如果原来的接口存在,减少对其引用---其实就是释放原接口。
*pp = lp;
return lp;
}
ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
{
IUnknown* pTemp = *pp;
*pp = NULL;
if (lp != NULL)
lp->QueryInterface(riid, (void**)pp);
if (pTemp)
pTemp->Release();
return *pp;
}
相关文章推荐
- Java 三种会抛 ConcurrentModificationException 异常的代码实例
- 异常
- 二十一天学通C++之使用try/catch捕获异常
- Android程序的Unable to instantiate activity ComponentInfo异常
- Oracle RAC OCR 磁盘组异常恢复
- python异常以及面向对象编程
- SSH异常解决
- 异常
- JOptionpane.showinputdialog 数据异常 处理
- 异常信息:ORA-01658: 无法为表空间 CWBASE001 中的段创建 INITIAL 区
- 异常
- 异常:org.hibernate.DuplicateMappingException: Duplicate class/entity mapping
- 如何捕获未捕获的异常
- 【大牛经验】探讨Java的异常与错误处理
- 用异常来处理错误----第一节 Java异常的概念
- iphone--MBProgressHUD 显示方向异常(keyWindow问题)
- Unhandled exception type SQLException 异常
- 10.22,关于java异常机制的讲解
- Linux fstab 格式异常导致 mount 时报错:no final newline at the end of /etc/fstab
- The current request is not a multipart request异常