18.04.2015 Views

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

VISUAL C++<br />

expected. It is better to pass unambiguous types to constructors, that is, types<br />

that are not themselves smart types with overloaded cast operators.<br />

// Perform QI of IUnknown.<br />

IUnknownPtr ipUnk = ipSmartPointer;<br />

// Ensure IUnknown* constructor of CComVariant is used.<br />

CComVariant myVar2(ipUnk.GetInterfacePtr());<br />

A common practice with smart pointers is to use Detach to return an object from<br />

a method call. When returning an interface pointer, the COM standard is to<br />

increment reference count of the [out] parameter inside the method implementation.<br />

It is the caller’s responsibility to call Release when the pointer is no longer<br />

required. Consequently, care must be taken to avoid calling Detach directly on a<br />

member variable. A typical pattern is shown below:<br />

STDMETHODIMP CFoo::get_Bar(IBar **pVal)<br />

{<br />

if (pVal==0) return E_POINTER;<br />

// Constructing a local smart pointer using another smart pointer<br />

// results in an AddRef (if pointer is not 0).<br />

IBarPtr ipBar(m_ipBar);<br />

// Detach will clear the local smart pointer, and the<br />

// interface is written into the output parameter.<br />

*pVal = ipBar.Detach();<br />

// This can be combined into one line:<br />

// *pVal = IBarPtr(m_ipBar).Detach();<br />

return S_OK;<br />

}<br />

The above pattern has the same result as the following code. Note that a conditional<br />

test for a zero pointer is required before AddRef can be called. Calling<br />

AddRef (or any method) on a zero pointer will result in an access violation<br />

exception and typically crash the application:<br />

STDMETHODIMP CFoo::get_Bar(IBar **pVal)<br />

{<br />

if (pVal==0) return E_POINTER;<br />

// Copy the interface pointer (no AddRef) into the output parameter.<br />

*pVal = m_ipBar;<br />

// Make sure interface pointer is nonzero before calling AddRef.<br />

if (*pVal)<br />

*pVal->AddRef();<br />

return S_OK;<br />

}<br />

When using a smart pointer to receive an object from an [out] parameter on a<br />

114 • <strong>ArcGIS</strong> <strong>Engine</strong> <strong>Developer</strong> <strong>Guide</strong>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!