问题
I have several interfaces, e.g. IA, IB, IC, and so on, that share common properties, e.g. Site. I would like to know how to reuse code for these interfaces (please save me the answer on COM aggregation).
Current implementation is as follows:
class CA
// ATL specific...
{
STDMETHODIMP get_Site(...) {...}
STDMETHODIMP put_Site(...) {...}
}
class BA
// ATL specific...
{
STDMETHODIMP get_Site(...) {...}
STDMETHODIMP put_Site(...) {...}
}
class CC
// ATL specific...
{
STDMETHODIMP get_Site(...) {...}
STDMETHODIMP put_Site(...) {...}
}
What I want to achieve (but cannot) is as follows.
template<typename T>
class SharedProperties
{
STDMETHODIMP get_Site(...) {...}
STDMETHODIMP put_Site(...) {...}
}
class CA :
// ATL specific...
SharedProperties<CA>
{
// properties are inherited and are accessible from IC
}
class BA
// ATL specific...
SharedProperties<CB>
{
// properties are inherited and are accessible from IB
}
class CC
// ATL specific...
SharedProperties<CC>
{
// properties are inherited and are accessible from IA
}
I came across this idea after reading up (http://vcfaq.mvps.org/com/7.htm) but the site does not have a working example and no matter how much I tried I could not get it to work. I keep getting "Cannot instantiate abstract class" because the pure virtual functions get_Site and put_Site are not implemented (as per the second snippet).
EDIT Do note that I am using VS2010. Sample implementation below:
class ATL_NO_VTABLE CArticle :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CArticle, &CLSID_Article>,
public IDispatchImpl<IArticle, &IID_IArticle, &LIBID_GeodeEdiLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CArticle()
{
}
回答1:
The compiler does not know that the methods get_Site and put_Siteimplement the methods from the interface. You need to inherit the SharedProperties class template from the corresponding interface. That's the argument to make SharedProperties a template at all.
interface IA
{
STDMETHOD(get_Site)() = 0;
STDMETHOD(put_Site)() = 0;
};
template<typename T>
class Sharedproperties : T
{
public:
STDMETHODIMP get_Site() { return E_NOTIMPL; };
STDMETHODIMP put_Site() { return E_NOTIMPL; };
};
class CAX : public IA
{
STDMETHOD(other)() { return S_OK; }
}
class CA: public Sharedproperties<CAX>
{
public:
CA() {}
};
Please note that the class CA is not directly inherited from the interface IA.
Edit: The VS2008 class wizard generates this inheritance for a simple ATL class object:
class ATL_NO_VTABLE CMyObject :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyObject, &CLSID_MyObject>,
IMyObject
where IMyObject is the in the IDL defined interface. So in ATL context you just need to replace the IMyObject inheritance:
class ATL_NO_VTABLE CMyObject :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyObject, &CLSID_MyObject>,
public Sharedproperties<MyIntermediateClass>
来源:https://stackoverflow.com/questions/10779834/atl-com-how-to-reuse-code-for-interface-method