在C++中,除了一般的指定基类名称的继承外,还有一种使用模版技术的继承,称之为模
版继承。请看如下代码,是偶从ATL的源代码中抽取出来的。
NOTE: Class A 想要变成com组件,需要写一堆东西,有一事就是从IDispatch间接继承,IA::IDispatch。这是传统的想把类A变成一个属于别个类B体系的方法:类A继承类B
模板类继承则提供了相反的方法,实现了组合方式,解耦。例如:类A想变成com组件体系中的IA,现在这样做: CComObject<A> IA; 我们使用IA即可,类A成了com组件的父类,不改变类A原有的类体系,实现了类A与com组件的组合
偶们不用管代码中的基类和派生类到底是干什么的,但这段向我们展示了一种可用的继
承技术。这种继承技术集成了C++的代码重用的优点(通过继承实现)和通用性的优点(通过
模版实现)
template <class Base>
class CComObject : public Base
{
public:
typedef Base _BaseClass;
CComObject(void* = NULL) throw()
{
_pAtlModule->Lock();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and
// also catch mismatched Release in debug builds
virtual ~CComObject() throw()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
_pAtlModule->Unlock();
}
//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{return _InternalQueryInterface(iid, ppvObject);}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) throw()
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
static HRESULT WINAPI CreateInstance(CComObject<Base>** pp) throw();
};
class CAtlModule;
__declspec(selectany) CAtlModule* _pAtlModule = NULL;