boost::shared_ptr and boost::weak_ptr

Started by
3 comments, last by Sneftel 17 years ago
Hi, I have in game objects created like this (approximately): typedef boost::shared_ptr<CClientObject> CObjectPtr; CobjectPtr camera = CObjectPtr(new CClientObject( "MainCamera", -100, OBJECT_CAMERA )); Now I am assigning 'controlstreams' to objects. These are links to Player Input, AI machines, or files comtaining command lists. I want to link to the CClientObject, but not using a boost::shared_ptr, since this increments the use_count. I tried passing the CObjectPtr by reference, but the use_count still increases. I then wanted to use a boost::weak_ptr in the CControlStream class to store the control streams target. This compiled okay. Unfortunately boost::weak_ptr doesn't have operator-> or get() methods to gain access to the object pointed to. So the ControlStream cannot send control messages to its target. (what is the point of boost::weak_ptr then?!) Can anyone advise how I can refer to a boost::shared_ptr's object without incrementing the use count? Doing so puts my resource managers into chaos! Thanks Si
Advertisement
It sounds like a boost::weak_ptr is what you want, this is how you use it:

boost::weak_ptr<Object> weak;void func(){    if(weak.expired())    {        std::cout << "Pointed-to object no longer exists!" << std::endl;    }    else    {        std::cout << "Pointed-to object exists, doing stuff." << std::endl;        boost::shared_ptr<Object> ptr = weak.lock();        ptr->DoStuff();    }}int main(){    // Create a shared_ptr and weak_ptr to an object    boost::shared_ptr<Object> obj(new Object);    weak = obj;    // Run func while the object exists    func();    // Run func after the object is destroyed    obj.reset();    func2();}


boost::weak_ptr maintains a reference to the object without affecting the reference count. This means the object could be destroyed at anytime (like in the above example) so in order to access the pointed-to object you to first check that it still exists and 'lock' the weak_ptr (creating a temporary shared_ptr and increasing the reference count) so that you can work with it. Once your finished the shared_ptr is destroyed (decrementing the reference count) and you keep your weak_ptr for the next time you want to use the object.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Thans for the fast response. I'll give it a try!

EDIT:

That works a treat! weak_ptrs are elegant!
Quote:Original post by sipickles
Unfortunately boost::weak_ptr doesn't have operator-> or get() methods to gain access to the object pointed to. So the ControlStream cannot send control messages to its target. (what is the point of boost::weak_ptr then?!)


Directly accessing a weak pointer wouldn't be a good idea -- in multithreading environments (or even just poorly done single thread ones), this could result in having the rug "pulled out from under you" (e.g. the object existed when you began, but then had the rug pulled out from under you).

As such, you must convert a weak pointer to a shared pointer (temporarily), as clearly outlined in the first paragraph of The Documentation. This avoids this problem, and allows you normal access.

EDIT: Beaten >_>
Calling expired() isn't necessary, and may cause a race condition in multithreaded situations. Just call lock(), and see whether the returned pointer is valid.

This topic is closed to new replies.

Advertisement