继承自定义的接口实现

目的:

首先从IDispatch派生一个接口IBaseNode:
interface IBaseNode : IDispatch{
[propget, id(1), helpstring("property ID")] HRESULT ID([out, retval] BSTR* pVal);
[propput, id(1), helpstring("property ID")] HRESULT ID([in] BSTR newVal);
[propget, id(2), helpstring("property Name")] HRESULT Name([out, retval] BSTR* pVal);
[propput, id(2), helpstring("property Name")] HRESULT Name([in] BSTR newVal);
};

然后想从IBaseNode派生出其它接口比如IDeriveNode:
nterface IDeriveNode : IBaseNode{
[propget, id(3), helpstring("property Title")] HRESULT Title([out, retval] BSTR* pVal);
[propput, id(3), helpstring("property Title")] HRESULT Title([in] BSTR newVal);
};

希望IBaseNode的实例类CBaseNode中实例公用的属性比如ID,Name等,然后其派生接口的实现类CDeriveNode再去实现私有属性。这样不同的派生类可以添加不同的属性,但不用重新实现基接口的方法。

试了好几种办法,CDeriveNode在编译时都报IBaseNode中定义的属法方法没有实现,属于抽象类,不能创建实例。

 

实现:(CSDN连接http://community.csdn.net/Expert/topic/5500/5500513.xml?temp=.9658319)

把IBaseNode的接口实例抽出来写成模板类:
template<class T>
class ATL_NO_VTABLE CBaseImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<T>
{
public:
CBaseImpl(void)
{
}

public:
STDMETHOD(get_ID)(BSTR* pVal);
STDMETHOD(put_ID)(BSTR newVal);
STDMETHOD(get_Name)(BSTR* pVal);
STDMETHOD(put_Name)(BSTR newVal);

protected:
CComBSTR m_bstrID;
CComBSTR m_bstrName;
};

template<class T>
STDMETHODIMP CBaseImpl<T>::get_ID(BSTR* pVal)
{
m_bstrID.CopyTo(pVal);

return S_OK;
}

template<class T>
STDMETHODIMP CBaseImpl<T>::put_ID(BSTR newVal)
{
m_bstrID = newVal;

return S_OK;
}

template<class T>
STDMETHODIMP CBaseImpl<T>::get_Name(BSTR* pVal)
{
m_bstrName.CopyTo(pVal);

return S_OK;
}

template<class T>
STDMETHODIMP CBaseImpl<T>::put_Name(BSTR newVal)
{
m_bstrName = newVal;

return S_OK;
}

然后CBaseNode定义改成:
class ATL_NO_VTABLE CBaseNode :
public CBaseImpl<IBaseNode>,
public CComCoClass<CBaseNode, &CLSID_BaseNode>
{
public:
CBaseNode()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_BASENODE)

BEGIN_COM_MAP(CBaseNode)
COM_INTERFACE_ENTRY(IBaseNode)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

CDeriveNode定义改成:
class ATL_NO_VTABLE CDeriveNode :
public CBaseImpl<IDeriveNode>,
public CComCoClass<CDeriveNode, &CLSID_DeriveNode>
{
public:
CDeriveNode()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_DERIVENODE)

BEGIN_COM_MAP(CDeriveNode)
COM_INTERFACE_ENTRY(IDeriveNode)
COM_INTERFACE_ENTRY(IBaseNode)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

Leave a Reply