Boost logo

Boost :

From: Jody Hagins (jody-boost-011304_at_[hidden])
Date: 2004-07-30 08:20:57


On Thu, 29 Jul 2004 22:05:22 +0100
"Andrew Shiels" <aeshiels_at_[hidden]> wrote:

> Im very new to boost, and have just started to intergrate the
> shared_ptr smart pointer into one of my applications. I am storing a
> lot of pointers (to objects) in a std::vector.
>
> typedef boost::shared_ptr<CMyClass> my_shared_ptr;
> typedef std::vector<my_shared_ptr> my_shared_ptr_vector;
>
> What i need to do is to additionally store a reference to the same
> objects(in the vector) in a CListCtrl (MFC). The CListCtrl allows you
> to associate a pointer with each item (row) in the list control.
>
> Before i used shared_ptr i used to add the data as below:
>
> CMyClass pItem = new CMyClass();
> my_vector->push_back(pItem);
> CListCtrl::SetItemData->SetItemData(iItemNumber, (DWORD)pItem);
>
> Now using shared_ptr (see below) i get a compiler error saying that it
> cannot convert from my_shared_ptr to DWORD.
>
> my_shared_ptr myPtr (new CMyClass();
> my_shared_ptr_vector->push_back(myPtr);
> CListCtrl::SetItemData->SetItemData(iItemNumber,
> reinterpret_cast<DWORD_PTR>(myPtr));

You will probably get a better answer from someone else who is forced to
code to the win32/mfc interface. However, in general, the reason this
does not work is because shared_ptr can not be converted to a DWORD_PTR
(I assume it is a pointer to a 32 bit word). If you *really* want to do
the above, then you should change the code to:

CListCtrl::SetItemData->SetItemData(iItemNumber,
static_cast<void*>(myPtr.get()));

assuming SetItemData takes a pointer type as its second argument... I
know nothing about this function...

However...

> My second question is if i was able to add the item data as ...
>
> CListCtrl::SetItemData->SetItemData(iItemNumber,
> reinterpret_cast<DWORD_PTR>(myPtr));
>
> ...would the internal reference counter be incremented in
> shared_ptr?
>
> My vector may be destroyed before my CListCtrl and I dont want the
> item data to be deleted until both are out of scope.

No, the reference count does not get incremented, becaue it is no longer
being treated as a shared_ptr. You have hijacked the internal pointer
from the shared_ptr. It still manages the lifetime of the underlying
object, but it does not know that you have kept the raw pointer. You
have to make sure the raw object stays around yourself.

There are several ways to do this, but if you MUST give away a raw
pointer to an object, then you also have to manage its lifetime in some
manner. A reasonable approach is to use boost::intrusive_ptr<> which
requires an embedded reference count on the object itself. Then, you
can call intrusive_ptr_add_ref() yourself before giving the raw pointer
to the SetItemData() call. However, you also must call
intrusive_ptr_release() when the CListCtrl is done with it as well, or
you will leak the object.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk