
On Thu, 29 Jul 2004 22:05:22 +0100 "Andrew Shiels" <aeshiels@dsl.pipex.com> 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.