I declared a COM interface and I have two implementations(classes) of the interface depending on input config. I also have a factory method that checks for input config and appropriately calls NEW on the class. In my class I implement AddRef() and Release() as per COM spec.
I declare a ComPtr and call the factory method to get access to above interface. I can do this two ways,
1) Return ComPtr from Factory method
ComPtr<ICaptureSource> ICaptureSource::CreateInstance(someConfig)
{
switch (someConfig)
{
case 1:
return (new CCaptureSource1()); >> Ref count in this class is initialized to 1
break;
case 2:
return (new CCaptureSource2()); >> Ref count in this class is initialized to 1
break;
default:
return nullptr;
}
}
ComPtr <ICaptureSource> captureSource;
captureSource = ICaptureSource::CreateInstance(someConfig);
After returning from above call, Ref count of captureSource is '2'. I was expecting it to be 1.
However with below code, Ref count is 1
2) Pass ComPtr address as parameter to factory method
HRESULT ICaptureSource::CreateInstance(someConfig, ICapturesource **ppv)
{
ICaptureSource *pTemp = nullptr;
switch (someConfig)
{
case 1:
pTemp = new CCaptureSource1(); >> Ref count in this class is initialized to 1
break;
case 2:
pTemp = new CCaptureSource2(); >> Ref count in this class is initialized to 1
break;
}
if (SUCCEEDED(hr) && (ppv != nullptr))
{
*ppv = pTemp;
}
return hr
}
ComPtr <ICaptureSource> captureSource;
hr = ICaptureSource::CreateInstance(someConfig, &captureSource);
captureSource ref count is now 1.
Kindly guide me why is there a difference in ref count in above two approaches and why returning an object is incrementing ref count (2), Vs setting object pointer to *ppv (ref count 1).
As it can be expected, approach (1) is causing memleak because ref count does not go to 0.
WRL
ComPtrinstance is automatically incrementing reference counter at the moment yournew CCaptureSource1()is converted to returned
ComPtr<ICaptureSource>This is behavior by design and as documented ("...automatically maintains a reference count for the underlying interface pointer..."). When your
captureSourcevariable goes out of scope, there will be a reference count decrement on your object.In your second approach you are attaching a raw interface pointer into
ComPtrinstance: you place a raw (meaning: not incremented by smart pointer class) pointer into*ppvso reference counter remains being one.ComPtrinstance will have the pointer attached without increment, but it will decrement it on destruction. This is how the reference counter reaches zero.