Boost logo

Boost Users :

Subject: [Boost-users] initializing intrusive_ptrs through library calls
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-04-26 11:47:54


I frequently use COM, and I've written an add_ref() and release() so that I
can use my COM objects with boost::intrusive_ptr. However, one generally
obtains these pointers through a library call that accepts a T** or a
void**, and returns a pointer that's already been AddRef'd the first time.
Normally it would go something like this:

template<typename T>
d3d_ptr<T> take_ptr(T* t) { return d3d_ptr<T>(t, false); }

ID3DXFont* pFont = NULL;
D3DXCreateFontIndirect(m_pDeviceObject, &fontDesc, &pFont);
m_spFont = take_ptr(pFont);

To remove these extra 2 lines I wrote the following class / function:

template<typename T>
class recv_by_addr_t
{
public:
    recv_by_addr_t(d3d_ptr<T>& r) : m_auto(r), m_raw(NULL) {}
    ~recv_by_addr_t() {m_auto = take_ptr(m_raw);}
    operator T**() { return &m_raw; }
private:
    T* m_raw;
    d3d_ptr<T>& m_auto;
};

template<typename T>
recv_by_addr_t<T> recv_by_addr(d3d_ptr<T>& rptr)
{
    return recv_by_addr_t<T>(rptr);
}

And I can now call the function like this:

D3DXCreateFontIndirect(m_pDeviceObject, &fontDesc, recv_by_addr(m_spFont));

I feel like this is pretty solid, but figured I should ask the gurus :)
Even in the case where the function errors out and sets the thing to NULL,
the original pointer should still get correctly released. Anything wrong
with this approach?



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net