C++ shared_singleton I actually feel bad posting "yet another singleton"... I wrote the following one many years ago and had recently found another application for it. We had many threads, each running the same function that requires the use of a boost::asio::io_service instance. It was best that all threads shared the same io_service instance and also that that instance be destroyed before main returned. That last requirement (whose validity I now question, but, whatever..) meant no global or static object.

Here's a function that returns an instance of an object wrapped in a shared_ptr. What's special about it though is that we keep an additional reference count so the singleton is eagerly destructed when the last shared_ptr is gone.

For example, if you call the function twice, you have two shared_ptrs, each with a ref-count of 1, but our singleton's ref-count is 2. On the other hand, if you call the function only once and copy the returned shared_ptr, the shared_ptr has a ref-count of 2 but our singleton's ref-count is at one. Either way, the singleton instance gets destructed when the last shared_ptr is destructed.

One disadvantage of this code is that the class is instantiated from its default constructor.

#include &lt;memory&gt;
#include &lt;mutex&gt;

// Deleter function given to the shared_ptr returned by get_shared_singleton.
template&lt;typename T&gt;
void release_shared(std::mutex&amp; m, int&amp; n, T*&amp; p)
{
    std::lock_guard&lt;std::mutex&gt; lg(m);
    if(!--n)
    {
        delete p;
        p = 0;
    }
}

template&lt;typename T&gt;
std::shared_ptr&lt;T&gt; get_shared_singleton()
{
    static std::mutex m;

    std::lock_guard&lt;std::mutex&gt; lg(m);

    static int n = 0;   // Ref count.
    static T* p = 0;    

    if(!p) p = new T();
    ++n;

    return std::shared_ptr&lt;T&gt;(p, std::bind(release_shared&lt;T&gt;, std::ref(m), std::ref(n), std::ref(p)));
}


The requirements, more clearly stated:


You wrote a function foo() that requires an instance of object X to perform its duty.
foo() can be invoked concurrently from different threads.
Concurrent foo()s must share the same instance of object X.
If no foo() is running, there must be no instance of object X alive.
foo() is in a library, you have no control of main() or the lifetime of threads that invoke foo().


What is the best code to provide a shared instance of an object that is both lazily-constructed and eagerly-destructed?
You can use a static weak_ptr in the function to cache the shared instance without extending its lifetime:

template&lt;typename T&gt;
std::shared_ptr&lt;T&gt; get_shared_instance()
{
    static std::mutex m;
    static std::weak_ptr&lt;T&gt; cache;

    std::lock_guard&lt;std::mutex&gt; lg(m);

    std::shared_ptr&lt;T&gt; shared = cache.lock();
    if (cache.expired()) {
        shared.reset(new T);
        cache = shared;
    }
    return shared;
}


So, the first caller will find a default-initialized weak_ptr counts as expired, and construct a new T.

While the first caller is active (and keeping its new T alive), concurrent callers will get the same object, cached in the weak_ptr.  When the last concurrent user is done, the object will be destroyed.

A subsequent caller will find the weak_ptr expired (same as before the first call), and create a new T ... etc. etc.