Sign in to follow this  
sipickles

boost::shared_ptr and boost::weak_ptr

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 >_>

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this