Skip to content

Instantly share code, notes, and snippets.

@cswiercz
Last active June 15, 2022 03:04
Show Gist options
  • Save cswiercz/4ccf72e5d5dd4bf93173193180c87506 to your computer and use it in GitHub Desktop.
Save cswiercz/4ccf72e5d5dd4bf93173193180c87506 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
}
@TerensTare
Copy link

There is a missing semicolon after return. Otherwise great job! One of my favourite C++ snippets aswell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment