Using weak_ptr

The weak_ptr holds a weakly referenced pointer to an object that is managed by a shared_ptr (or by multiple shared_ptr instances). The weak_ptr does not affect the strong ref count. You typically construct a weak_ptr out of a shared_ptr, and then when you need to access the underlying object, you call lock() on the weak_ptr which gives you a shared_ptr (with ref count incremented). One use of weak_ptr types is to help avoid circular references, which often leads to memory leaks as objects continue to remain in memory. Another example would be cached access to objects that may or may not be alive in memory. So you’d store the weak_ptrs and whenever you need to access the object, you’d check to see if the object’s alive, and create a shared_ptr from the weak_ptr as needed. The code snippet below shows such a pattern.

class NumberStoreCache
{
private:
  unordered_map<int, weak_ptr<NumberStore>> cache;

  shared_ptr<NumberStore> AddToCache(int number)
  {
    shared_ptr<NumberStore> store = make_shared<NumberStore>(
        number);
    weak_ptr<NumberStore> weak(store);
    cache[number] = weak;
    return store;
  }

public:
  shared_ptr<NumberStore> GetNumberStore(int number)
  {
    if (cache.find(number) == cache.end())
    {
      return AddToCache(number); // call 1 
    }
    else
    {
      weak_ptr<NumberStore> weak = cache[number];
      if (weak.expired())
      {
        return AddToCache(number); // call 2
      }
      else
      {
        return weak.lock(); // call3
      }
    }
  }
};

void Foo()
{
  NumberStoreCache nsCache;
  auto ns1 = nsCache.GetNumberStore(10); // call 1
  ns1.reset();
  auto ns2 = nsCache.GetNumberStore(10); // call 2
  auto ns3 = nsCache.GetNumberStore(10); // call 3
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s