📄 hxsmartptr.h
字号:
HX_PRIVATE_SMART_POINTER_INLINE( CLASS_NAME, IUnknown, HX_PRIVATE_BLANK, HX_PRIVATE_BLANK )
/*!
@defined HX_IUNKNOWN_CONST_SMART_POINTER_INLINE
@abstract
Declare a const smart pointer of name CLASS_NAME which points to an
IUnknown interface. Inline definitions of all functions.
*/
#define HX_IUNKNOWN_CONST_SMART_POINTER_INLINE( CLASS_NAME ) \
HX_PRIVATE_SMART_POINTER_INLINE( CLASS_NAME, IUnknown, const, HX_PRIVATE_BLANK )
// ---------------------------------------------------------------------
// The macros below here should not be used directly. They might
// change in future implementations
// ---------------------------------------------------------------------
// The IUnknown functions macros have been included
// to reduce code duplication. If we just attempt to use the normal
// macros for creating an IUnknown smart pointer we end up with compile
// errors because the copy constructor and assignment ops are duplicated.
// The HX_PRIVATE_NON_IUNKNOWN_FUNCTIONS macro separates out a copy
// constructor / assignment op that are needed in the non-IUnknown versions
// but would cause errors in the IUnknown versions.
#define HX_PRIVATE_NON_IUNKNOWN_FUNCTIONS( CLASS_NAME, INTERFACE, QUALIFIERS ) \
CLASS_NAME(INTERFACE QUALIFIERS* pact) \
: pActual(NULL) \
{ \
if( pact ) \
{ \
pActual = (INTERFACE*) pact; \
pActual->AddRef(); \
} \
} \
CLASS_NAME& operator =( INTERFACE QUALIFIERS* pNew ) \
{ \
if( pNew != pActual ) \
{ \
INTERFACE* pTemp = pActual; \
pActual = (INTERFACE*) pNew; \
if( pActual ) \
{ \
pActual->AddRef(); \
} \
HX_RELEASE( pTemp ); \
} \
return *this; \
} \
#define HX_PRIVATE_SMART_POINTER_INLINE( CLASS_NAME, INTERFACE, QUALIFIERS, NON_IUNKNOWN_DEFINITIONS ) \
\
class CLASS_NAME \
{ \
public: \
CLASS_NAME() \
: pActual(NULL) \
{} \
\
CLASS_NAME( const CLASS_NAME& rspact ) \
: pActual(NULL) \
{ \
if( rspact.pActual ) \
{ \
pActual = rspact.pActual; \
pActual->AddRef(); \
} \
} \
\
CLASS_NAME(IUnknown QUALIFIERS* punk) \
: pActual(NULL) \
{ \
if(punk) \
((IUnknown*) punk)->QueryInterface( IID_##INTERFACE, ( void** )( &pActual ) ); \
} \
CLASS_NAME& operator =( IUnknown QUALIFIERS* punkNew ) \
{ \
if( punkNew != pActual ) \
{ \
INTERFACE* pTemp = pActual; \
if(punkNew) \
{ \
((IUnknown*) punkNew)->QueryInterface( IID_##INTERFACE, ( void** )( &pActual ) ); \
} \
else \
{ \
pActual = NULL; \
} \
HX_RELEASE( pTemp ); \
} \
return *this; \
} \
\
CLASS_NAME( IHXCommonClassFactory* pIObjectSource, REFCLSID clsid, HX_RESULT* pResult = NULL ) \
: pActual(NULL) \
{ \
HX_ASSERT(pIObjectSource); \
IUnknown* pIUnk = NULL; \
HX_RESULT result = pIObjectSource->CreateInstance( clsid, (void**)&pIUnk ); \
if (SUCCEEDED(result)) \
{ \
HX_ASSERT(pIUnk); \
result = pIUnk->QueryInterface( IID_##INTERFACE, ( void** )( &pActual ) ); \
pIUnk->Release(); \
} \
if( pResult ) \
{ \
*pResult = result; \
} \
} \
\
NON_IUNKNOWN_DEFINITIONS \
\
~CLASS_NAME() \
{ HX_RELEASE (pActual); } \
\
class INTERFACE##_InternalSP : public INTERFACE \
{ \
private: \
virtual ULONG32 STDMETHODCALLTYPE AddRef () PURE; \
virtual ULONG32 STDMETHODCALLTYPE Release () PURE; \
}; \
\
INTERFACE##_InternalSP QUALIFIERS* operator -> () const \
{HX_ASSERT(pActual);return (INTERFACE##_InternalSP*) pActual;} \
\
INTERFACE##_InternalSP QUALIFIERS& operator * () const \
{HX_ASSERT(pActual);return *((INTERFACE##_InternalSP*) pActual);} \
\
CLASS_NAME& operator =( const CLASS_NAME& rspact ) \
{*this = rspact.pActual; return *this;} \
\
\
\
HX_RESULT Query(IUnknown QUALIFIERS* punkNew) \
{ \
HX_RESULT result = HXR_INVALID_PARAMETER; \
if( punkNew ) \
{ \
result = HXR_OK; \
if( punkNew != pActual ) \
{ \
INTERFACE* pTemp = NULL; \
result = ((IUnknown*) punkNew)->QueryInterface( IID_##INTERFACE, ( void** )( &pTemp ) ); \
if( SUCCEEDED( result ) ) \
{ \
HX_RELEASE( pActual ); \
pActual = pTemp; \
} \
} \
} \
return result; \
} \
\
BOOL IsValid() const \
{return pActual!=NULL;} \
\
INTERFACE** AsInOutParam () \
{ HX_RELEASE (pActual); return &pActual; } \
\
INTERFACE QUALIFIERS* Ptr() const \
{return pActual;} \
\
void AsPtr( INTERFACE QUALIFIERS** ppActual ) const \
{ \
HX_ASSERT(pActual); \
pActual->AddRef (); \
*ppActual = pActual; \
} \
\
void AsUnknown( IUnknown QUALIFIERS** ppIUnknown ) const \
{ \
HX_ASSERT(pActual); \
pActual->QueryInterface \
( \
IID_IUnknown, \
( void** )ppIUnknown \
); \
} \
\
void Clear () \
{ HX_RELEASE (pActual); } \
\
private: \
INTERFACE* pActual; \
}
#define HX_PRIVATE_BLANK
HX_IUNKNOWN_SMART_POINTER_INLINE( SPIUnknown );
HX_IUNKNOWN_CONST_SMART_POINTER_INLINE( SPCIUnknown );
// Since we are guaranteed that SPIUnknown and SPCIUnknown will be storing
// the unique IUnknown pointer we can just compare the results of the Ptr function.
inline BOOL operator ==( const SPIUnknown& sp1, const SPIUnknown& sp2 )
{
return sp1.Ptr() == sp2.Ptr();
}
inline BOOL operator ==( const SPCIUnknown& spc1, const SPCIUnknown& spc2 )
{
return spc1.Ptr() == spc2.Ptr();
}
/* These cannot be activated without letting everybody know. Some code might
fail to compile:
IRCAClickable* p = 0;
if (p == SPIUnknown(p)) //is ambigous
{ ... }
inline BOOL operator ==( const SPIUnknown& sp1, const SPCIUnknown& spc2 )
{
return sp1.Ptr() == spc2.Ptr();
}
inline BOOL operator ==( const SPCIUnknown& spc1, const SPIUnknown& sp2 )
{
return spc1.Ptr() == sp2.Ptr();
}
*/
inline BOOL operator !=( const SPIUnknown& sp1, const SPIUnknown& sp2 )
{
return ! ( sp1 == sp2 );
}
inline BOOL operator !=( const SPCIUnknown& spc1, const SPCIUnknown& spc2 )
{
return ! ( spc1 == spc2 );
}
/*
inline BOOL operator !=( const SPIUnknown& sp1, const SPCIUnknown& spc2 )
{
return ! ( sp1 == spc2 );
}
inline BOOL operator !=( const SPCIUnknown& spc1, const SPIUnknown& sp2 )
{
return ! ( spc1 == sp2 );
}
*/
#endif // _HXSMARTPTR_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -