Skip to content

Instantly share code, notes, and snippets.

@davehorner
Forked from cswiercz/cached_factory.cpp
Created November 5, 2021 01:06
Show Gist options
  • Save davehorner/2b9ee23053088a4e5c1f90225d5e9ec7 to your computer and use it in GitHub Desktop.
Save davehorner/2b9ee23053088a4e5c1f90225d5e9ec7 to your computer and use it in GitHub Desktop.
Herb Sutter's favorite sub-10 line C++ snippet: Factory w/Cache
/*
Cached Factory
Sometimes you want to make objects with a lifetime managed
by their target owner but you also want to hold reference
to them in a custom cache. The target owner, naturally, will
be given a shared_ptr to the output object. However, we don't
want the lifetime of the output object to be tied to the
internal cache. I.e. if the owner dies then the object should
die even if referenced in the cache.
The solution is to have the cache contain weak_ptr's to the
created objects. These weak_ptrs are appropriately converted
to shared_ptrs, with correct ownership properties, when
obtained from the cache.
Furthermore, we want this cache to be thread-safe: multiple
threads should only be allowed to access a given element
of the cache one at a time. (However, multiple threads can
certainly access other cached objects.)
*/
shared_ptr<Widget> make_widget(int id) {
static map<int, weak_ptr<width>> cache; // "static" is important here: one mutex and
static mutex mut_cache; // cache for all threads
lock_guard<mutex> hold(mut_cache); // RAII-style locking for the rest of the routine
auto sp = cache[id].lock(); // returns a shared_ptr with "appropriate" ownership props
if (!sp) // (see weak_ptr.lock() documentation)
cache[id] = sp = load_widget(id); // create the widget if it doesn't exist (as a
// shared_ptr to the heap-allocated resource)
return sp
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment