views:

146

answers:

2

If I have a C++ class, X, which implements the COM interfaces IY and IZ, and I have a pointer y to the IY interface of an object of type X, and I do this:

IZ *z = dynamic_cast<IZ *> ( y );

That doesn't bump the object's reference count, does it? I don't have to do a Release() to account for it, right?

If it matters, I'm using ATL/COM.

I'm guessing the answer is "no it doesn't bump the reference count, and no you don't have to Release()", but I want to make sure.

Thanks in advance.

+3  A: 

dynamic_cast must not be used on multiple reasons:

  • You don't know if destination supports RTTI
  • You not sure if OLE doesn't create proxy for you
  • ...

Instead use QueryInterface - it would done what you want.

Even if you sure in question above - casting doesn't changes refcounter

Dewfy
Yes, yes and yes again. You even don't know if the implementation is really in C++. Use QueryInterface() - it's a very close equivalent of dynamic_cast that works regardless of different interop issues.
sharptooth
+3  A: 

Reference counts for COM objects are incremented when someone calls IUnknown::AddRef(). QueryInterface(), according to COM rules since it gives out a new interface pointer, internally calls AddRef().

In your posted code, you're not calling AddRef(), and you're not calling any function that might call AddRef(), so why would you think the reference count would be incremented?

Despite what ATL/MFC does to one's brain, there is no magic involved. When in doubt, you can always view the disassembly in VS and step through it and prove to yourself that AddRef() isn't being called.

Edit: And I want to reiterate what Dewfy said, don't do this. Use QueryInterface(). Or CComQIPtr<> (if you really must).

Further edit: If you use CComPtr<> and CComQIPtr<> then you don't have to call Release() and much of the burden of figuring out the proper ref-counting is alleviated. You should really consider using them.

jeffamaphone