
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)); 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. Thanks Andy

Andrew, (I'm top posting since for some reason auto '>' for your original text is defeated with this particular message) One issue you mention is lifetime. I assume you have a either a CListCtrl or CListView derived class. This class should have it's own vector<shared_ptr>. Then the lifetime of the listview items is ensured. No you can NOT use a casted shared_ptr in this fashion. You can reinterpret_cast<DWORD_PTR>(&*my_shared_ptr) if you feel you must. This will NOT increment any reference count, and as you found is not safe. The CListCrtrl primarily traffics in indices(LV_ITEM::item), so I generally forego the item data and just access vector<shared_ptr<>>[LV_ITEM::item] directly. In fact, specifying LVS_OWNERDATA style, I get much better performance and less memory usage than using the set item data approaches. ----------------- Jeff Flinn Applied Dynamics, International "Andrew Shiels" <aeshiels@dsl.pipex.com> wrote in message news:005301c475af$c2fb9250$08b15651@andy... 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)); 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. Thanks Andy _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

"Jeff Flinn" <TriumphSprint2000@hotmail.com> wrote in message news:cedhqq$9ur$1@sea.gmane.org...
Andrew,
(I'm top posting since for some reason auto '>' for your original text is defeated with this particular message)
One issue you mention is lifetime. I assume you have a either a CListCtrl or CListView derived class. This class should have it's own vector<shared_ptr>. Then the lifetime of the listview items is ensured.
No you can NOT use a casted shared_ptr in this fashion. You can reinterpret_cast<DWORD_PTR>(&*my_shared_ptr) if you feel you must. This will
Oops, use my_shred_ptr.get() as Jody mentioned. ----------------- Jeff Flinn Applied Dynamics, International

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.
participants (3)
-
Andrew Shiels
-
Jeff Flinn
-
Jody Hagins