Search code examples
c++comatlfactory-pattern

Factory-pattern with CComObjects


I have a shared base class CMyBase that is further divided into subclasses CMyFirst and CMySecond. How can I implement a factory interface for clients so that they don't need to know which of the children was created using CComObjects?

Essentially what I'm trying to do is this:

CMyBase* CFactory::Create
{
    CMyBase* pInst = NULL;
    if (something)
    {
        pInst = new CMyFirst();
    }
    else
    {
        pInst = new CMySecond();
    }
    return pInst;
}

But how can I create instance of a child COM object?

CComObject<CMyBase>* CFactory::Create
{
    HRESULT hr = E_FAIL;
    CComObject<CMyBase>* pInst = NULL;

    if (something)
    {
        hr = CComObject<CMyFirst>::CreateInstance(&pInst); // compiler error (see below)
    }
    else
    {
         hr = CComObject<CMySecond>::CreateInstance(&pInst); // compiler error (see below)
    }

    if (SUCCEEDED(hr))
    {
        pInst->AddRef();
    }
    return pInst;
}

I understand why I get this error, but how can I do this otherwise?

error C2664: 'ATL::CComObject<Base>::CreateInstance' : cannot convert parameter 1 from 'ATL::CComObject<Base> *' to 'ATL::CComObject<Base> **'

Solution

  • Create the derived class first, then cast it back to base before returning.

    One example:

    CComObject<CMyBase>* CFactory::Create
    {
        HRESULT hr = E_FAIL;
        CComObject<CMyBase>* pInst = NULL;
    
        if (something)
        {
            CComObject<CMyFirst>* pFirst = NULL;
            hr = CComObject<CMyFirst>::CreateInstance(&pFirst);
            pInst = (CComObject<CMyBase>*)pFirst;
        }
        else
        {
            CComObject<CMySecond>* pSecond = NULL;
            hr = CComObject<CMySecond>::CreateInstance(&pSecond);
            pInst = (CComObject<CMyBase>*)pSecond;
        }
    
        if (SUCCEEDED(hr))
        {
            pInst->AddRef();
        }
        return pInst;
    }