smartptr.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- //
- //
- // Macro implementation of "Smart Pointers" to COM interfaces
- //
- // Description:
- //
- // A SmartPointer is a class that contains a pointer, but acts like it
- // *is* the contained pointer. When used it helps enforce correct usage
- // of the pointer it contains. In this case it provides the following
- // safeguards:
- // HX_ASSERT if the contained pointer is NULL when you attempt to
- // use it.
- // HX_ASSERT if you attempt to replace a valid pointer without
- // releasing it.
- // Automatically AddRef() a pointer during assignment.
- // Automatically QI() an incoming pointer to the correct type
- // during assignment.
- // Automatically Release() an existing pointer during assignment.
- // Automatically Release() an existing pointer during destruction.
- //
- // SmartPointers also simplify usage. Example:
- //
- // ReadDone(HX_RESULT status, IUnknown* pbufData)
- // {
- // DECLARE_SMART_POINTER(IHXBuffer) spbufData;
- //
- // spbufData = pbufData;
- //
- // if(spbufData.IsValid())
- // {
- // // Use the Pointer
- // cout << spbufData->GetBuffer() << endl;
- // }
- // }
- // This example has no memory leaks. In the Assignment the IUnknown
- // pointer is QI'd for the IHXBuffer. If the QI had failed, then
- // the IsValid test would fail too. Even if the IsValid Test was
- // forgotten, spbufData->GetBuffer() would cause an assertion if
- // the QI had failed.
- //
- // Usage Tips:
- //
- // Should Not use SmartPointers as function parameters. ie:
- // ReadDone(HX_RESULT status, DECLARE_SMART_POINTER_UNKNOWN spbufData)
- // Cannot use SmartPointers as List elements.
- //
- // Macros Defined in this file:
- //
- // DECLARE_SMART_POINTER_UNKNOWN
- // This Macro is used to create a SmartPointer to an IUnknown
- // interface.
- // Example: DECLARE_SMART_POINTER_UNKNOWN m_spunkContext;
- //
- // DEFINE_SMART_POINTER(IACTUAL)
- // This Macro is used to define a SmartPointer class for any
- // interface other than IUnknown. It should be used in the header
- // file where the interface is defined.
- // Example: DEFINE_SMART_POINTER(IHXBuffer);
- //
- // IMPLEMENT_SMART_POINTER(IACTUAL)
- // This Macro is used to Implement a SmartPointer class for any
- // interface other than IUnknown. It should be used in a cpp
- // file that is linked into each binary.
- // Example: IMPLEMENT_SMART_POINTER(IHXBuffer)
- //
- // DECLARE_SMART_POINTER(IACTUAL)
- // This Macro is used to create a SmartPointer to any interface other
- // than IUnknown. The header file that contains the call to
- // IMPLEMENT_SMART_POINTER(IACTUAL) must be included before this macro
- // can be used.
- // Example: DECLARE_SMART_POINTER(IHXBuffer) m_spbufData;
- //
- //
- #ifndef _SMARTPTR_H_
- #define _SMARTPTR_H_
- #include "hxassert.h"
- class _CIUnknown_SP
- {
- public:
- _CIUnknown_SP() : m_pUnk(NULL)
- {}
- _CIUnknown_SP(_CIUnknown_SP& rspunk) : m_pUnk(NULL)
- {*this = rspunk.m_pUnk;}
- _CIUnknown_SP(IUnknown* punk) : m_pUnk(NULL)
- {*this = punk;}
- ~_CIUnknown_SP()
- {Release();}
- operator IUnknown* ()
- {return m_pUnk;}
- operator const IUnknown* () const
- {return m_pUnk;}
- IUnknown* operator -> () const
- {HX_ASSERT(m_pUnk);return m_pUnk;}
- IUnknown& operator * () const
- {HX_ASSERT(m_pUnk);return *m_pUnk;}
- IUnknown** operator & ()
- {HX_ASSERT(!m_pUnk);return &m_pUnk;}
- _CIUnknown_SP& operator = (IUnknown* punkNew)
- {
- Release();
- if(punkNew)
- {
- m_pUnk = punkNew;
- m_pUnk->AddRef();
- }
- return *this;
- }
- BOOL operator ! () const
- {return !IsValid();}
- BOOL IsValid() const
- {return (m_pUnk!=NULL);}
- IUnknown*& ptr_reference()
- {HX_ASSERT(!m_pUnk);return m_pUnk;}
- IUnknown* AsUnknown() const
- {
- HX_ASSERT(m_pUnk);
- IUnknown* punkOut = m_pUnk;
- punkOut->AddRef();
- return punkOut;
- }
- void Release()
- {HX_RELEASE(m_pUnk);}
- private:
- IUnknown* m_pUnk;
- };
- #define DECLARE_SMART_POINTER_UNKNOWN
- _CIUnknown_SP
- #define DEFINE_SMART_POINTER(IACTUAL)
- class _C##IACTUAL##_SP
- {
- public:
- _C##IACTUAL##_SP();
- _C##IACTUAL##_SP(_C##IACTUAL##_SP& rspact);
- _C##IACTUAL##_SP(IACTUAL* pact);
- _C##IACTUAL##_SP(IUnknown* punk);
- ~_C##IACTUAL##_SP();
-
- operator IACTUAL* ();
- operator const IACTUAL* () const;
-
- IACTUAL* operator -> () const;
- IACTUAL& operator * () const;
- IACTUAL** operator & ();
-
- _C##IACTUAL##_SP& operator = (IACTUAL* pNew);
- _C##IACTUAL##_SP& operator = (IUnknown* punkNew);
-
- BOOL operator ! () const;
- BOOL IsValid() const;
-
- IACTUAL*& ptr_reference();
- IUnknown* AsUnknown() const;
- void Release();
- private:
- IACTUAL* pActual;
-
- };
- #define IMPLEMENT_SMART_POINTER(IACTUAL)
- DEFINE_SMART_POINTER(IACTUAL)
-
- _C##IACTUAL##_SP::_C##IACTUAL##_SP()
- : pActual(NULL)
- {}
-
- _C##IACTUAL##_SP::_C##IACTUAL##_SP
- (
- _C##IACTUAL##_SP& rspact
- )
- : pActual(NULL)
- {*this = rspact.pActual;}
-
- _C##IACTUAL##_SP::_C##IACTUAL##_SP(IACTUAL* pact)
- : pActual(NULL)
- {*this = pact;}
-
- _C##IACTUAL##_SP::_C##IACTUAL##_SP(IUnknown* punk)
- : pActual(NULL)
- {*this = punk;}
-
- _C##IACTUAL##_SP::~_C##IACTUAL##_SP()
- {Release();}
-
- _C##IACTUAL##_SP::operator IACTUAL* ()
- {return pActual;}
-
- _C##IACTUAL##_SP::operator const IACTUAL* () const
- {return pActual;}
-
- IACTUAL* _C##IACTUAL##_SP::operator -> () const
- {HX_ASSERT(pActual);return pActual;}
-
- IACTUAL& _C##IACTUAL##_SP::operator * () const
- {HX_ASSERT(pActual);return *pActual;}
-
- IACTUAL** _C##IACTUAL##_SP::operator & ()
- {HX_ASSERT(!pActual);return &pActual;}
-
- _C##IACTUAL##_SP& _C##IACTUAL##_SP::operator =
- (
- IACTUAL* pNew
- )
- {
- Release();
- if(pNew)
- {
- pActual = pNew;
- pActual->AddRef();
- }
- return *this;
- }
-
- _C##IACTUAL##_SP& _C##IACTUAL##_SP::operator =
- (
- IUnknown* punkNew
- )
- {
- Release();
- if(punkNew)
- {
- punkNew->QueryInterface
- (
- IID_##IACTUAL,
- (void**)&pActual
- );
- }
- return *this;
- }
-
- BOOL _C##IACTUAL##_SP::operator ! () const
- {return !IsValid();}
-
- BOOL _C##IACTUAL##_SP::IsValid() const
- {return pActual!=NULL;}
-
- IACTUAL*& _C##IACTUAL##_SP::ptr_reference()
- {HX_ASSERT(!pActual);return pActual;}
-
- IUnknown* _C##IACTUAL##_SP::AsUnknown() const
- {
- HX_ASSERT(pActual);
- IUnknown* punkOut;
- pActual->QueryInterface
- (
- IID_IUnknown,
- (void**)&punkOut
- );
- return punkOut;
- }
-
- void _C##IACTUAL##_SP::Release()
- {HX_RELEASE(pActual);}
- #define DECLARE_SMART_POINTER(IACTUAL)
- _C##IACTUAL##_SP
- #define DEFINE_WRAPPED_POINTER(CACTUAL)
- class _C##CACTUAL##_WP
- {
- public:
- _C##CACTUAL##_WP();
- _C##CACTUAL##_WP(const _C##CACTUAL##_WP& rspact);
- _C##CACTUAL##_WP(const _C##CACTUAL##_SP& rspact);
- _C##CACTUAL##_WP(const CACTUAL* pActual);
- ~_C##CACTUAL##_WP();
-
- _C##CACTUAL##_WP& operator=
- (
- const _C##CACTUAL##_WP& rspact
- );
-
- void wrapped_ptr(const CACTUAL* pNew);
- const CACTUAL* wrapped_ptr() const;
- CACTUAL* wrapped_ptr();
-
- BOOL IsValid() const;
-
- void Empty();
- private:
- CACTUAL* pActual;
- };
- #define IMPLEMENT_WRAPPED_POINTER(CACTUAL)
- DEFINE_WRAPPED_POINTER(CACTUAL)
-
- _C##CACTUAL##_WP::_C##CACTUAL##_WP()
- : pActual(NULL)
- {}
- _C##CACTUAL##_WP::_C##CACTUAL##_WP
- (
- const _C##CACTUAL##_WP& rspact
- )
- : pActual(NULL)
- {wrapped_ptr(rspact.pActual);}
- _C##CACTUAL##_WP::_C##CACTUAL##_WP
- (
- const _C##CACTUAL##_SP& rspact
- )
- : pActual(NULL)
- {wrapped_ptr(rspact);}
- _C##CACTUAL##_WP::_C##CACTUAL##_WP
- (
- const CACTUAL* pActual
- )
- : pActual(NULL)
- {wrapped_ptr(pActual);}
- _C##CACTUAL##_WP::~_C##CACTUAL##_WP()
- {Empty();}
-
- _C##CACTUAL##_WP&
- _C##CACTUAL##_WP::operator=
- (
- const _C##CACTUAL##_WP& rspact
- )
- {wrapped_ptr(rspact.pActual); return *this;}
-
- void _C##CACTUAL##_WP::wrapped_ptr
- (
- const CACTUAL* pNew
- )
- {
- Empty();
- if(pNew)
- {
- pActual = (CACTUAL*)pNew;
- pActual->AddRef();
- }
- return;
- }
- const CACTUAL* _C##CACTUAL##_WP::wrapped_ptr() const
- {
- HX_ASSERT(pActual);
- return pActual;
- }
- CACTUAL* _C##CACTUAL##_WP::wrapped_ptr()
- {
- HX_ASSERT(pActual);
- return pActual;
- }
-
- BOOL _C##CACTUAL##_WP::IsValid() const
- {return (pActual != NULL);}
-
- void _C##CACTUAL##_WP::Empty()
- {HX_RELEASE(pActual);}
- #define WRAPPED_POINTER(CACTUAL)
- _C##CACTUAL##_WP
- #endif // _SMARTPTR_H_