Re: Instantiating ComObjects - best practice
"Alexander Lamaison" <newsgroups@lammy.co.uk> wrote in message
news:u6Yt5Re7IHA.1952@TK2MSFTNGP02.phx.gbl
My question is about the recommended way to initialising ATL interface
implementations (i.e. ComObjects) with values.
At the moment my programs are littered with code like the following:
IMyInterface pFace;
CComObject<CMyObject> *pObj;
hr = CComObject<CMyObject>::CreateInstance( &pObj );
if(SUCCEEDED(hr)) // Perform implementation-specific initialisation
{
pObj->AddRef();
hr = pObj->Initialize( some stuff specific to implementation );
if (SUCCEEDED(hr))
{
hr = pObj->QueryInterface( __uuidof(IMyInterface), &pFace );
}
pObj->Release();
}
Yes, that's about right. That's how you have to do it.
Of course, you don't have to "litter" your code with this. Write a
static CMyObject::MakeInstance function that does all this and returns a
properly AddRef'ed interface pointer.
I've also seen people do this which looks a little cleaner:
CComPtr<IMyInterface> spFace;
hr = spFace.CoCreateInstance( __uuidof(CMyObject) );
if (SUCCEEDED(hr))
{
static_cast<CMyObject *>(spFace.p)->Initialize( some imp-specific
); }
While it would work, I personally prefer the first variant.
Is the second way in any way inferior to the first
The second way only works on creatable objects - those with a CLSID
registered in the registry. More often than not, you use
CComObject::CreateInstance to create an instance of non-coclass object -
one that is not externally creatable.
Also, if somebody modifies your CLSID registration (e.g. with TreatAs
clause), this code will fail spectacularly.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925