1

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()
    {
    }
Telemat
  • 398
  • 2
  • 14
  • Which class is abstract and can't be instantiated? – sharptooth May 28 '12 at 06:03
  • Shouldn't `SharedProperties::get_Site` and `SharedProperties::put_Site` be virtual? – JoeG May 28 '12 at 08:06
  • They are, but if you are familiar with ATL I am sure you will get the point. The snippet is not actual source code. It is there for illustration purposes only. – Telemat May 28 '12 at 09:09
  • No can do, you'd need to define an IShared interface that all of these classes implement. With the disadvantage that the client code will have to QI it, much like aggregation. You have to write the Site methods in each, you can delegate to a common implementation. – Hans Passant May 28 '12 at 10:11

1 Answers1

0

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>
harper
  • 13,345
  • 8
  • 56
  • 105
  • You have placed an intermediate class in the inheritance hierarchy. It is a neat solution but it does not work in the context of ATL because class CA does not inherit *directly* from IA. – Telemat May 28 '12 at 09:07
  • The class template must inherit from the intermediate class in that case. I have edited the sample code to illustrate this case. – harper May 28 '12 at 09:27
  • This is weird, but your solution does makes sense. Please refer to my edited post for the code generated by VS2010. – Telemat May 28 '12 at 09:44