Thread-safe "singleton" that destroys object when not used anymore
The problem with the above code is that it doing two things with one piece of code.

1: Singleton Creation.
2: Singelton LifeSpan.

I would separate these out into two separate classes.

The creation is done via an abstract factory (MySingletonFactory) but lifespan is controlled via explicit factory classes that are defined for the situation (so your code does not define the life span of the singleton).

The other issue of the above code is that I have seen this not working because of the way global variables are created in libraries. When these libraries are linked together it is not required to remove duplicate variables (as all variables were already resolved as much as possible during compilation). The linking phase will only try and resolve unresolved dependencies not all linkers will try and remove duplicated global variables (though I suppose this will depend on how sophisticated the linker is).

Here is how I would resolve the problem (by removing globals (using static storage function scope variables)).

Interfaces

#include &lt;memory&gt;
#include &lt;iostream&gt;
#include &lt;cstdlib&gt;

class MySingleInterface
{
    public:
        virtual ~MySingleInterface() {}

        virtual int doWork() = 0;
};
class MySingleFactoryInterface
{
    public:
        virtual ~MySingleFactoryInterface() {}
        virtual std::shared_ptr&lt;MySingleInterface&gt;  createTheObject() = 0;
};


Abstract Factory (I think?)

class MySingletonFactory
{
    private:
        friend class MySingleInterface;
        static MySingleFactoryInterface&amp; getCurrentFactory(MySingleFactoryInterface* replace)
        {
            // Do not strictly need a default factory.
            // But it is nice to have one for standard (default)
            // operations. Then you only specify one in non standard
            // situations like testing. 
            static MyDefaultSingeltonFactory           defaultFactory;

            // The current factory we are using.
            static MySingleFactoryInterface*           currentFactory = &amp;defaultFactory;
            if (replace)
            {
                std::swap(replace, currentFactory);
            }
            else
            {
                replace = currentFactory;
            }
            return *replace;
        }
    public:
        static std::shared_ptr&lt;MySingleInterface&gt; getInstance()
        {
            return getCurrentFactory(nullptr).createTheObject();
        }
        static MySingleFactoryInterface&amp; setFactory(MySingleFactoryInterface&amp; alternativeFactory)
        {
             return getCurrentFactory(&amp;alternativeFactory);
        }
};


Example Default Singleton

class MyDefaultSingeltonFactory;
class MyDefaultSingleton: public MySingleInterface
{
    private:
        friend class MyDefaultSingeltonFactory;
        MyDefaultSingleton(){}
    public:
        virtual int doWork() override {static int value; return value++;}   // Normal operation.
};
class MyDefaultSingeltonFactory: public MySingleFactoryInterface
{
    // A Normal Singleton factory.
    // The singelton lives from creation until the end of the program.
    // Note: This is the behavior of this factory does not need to
    //       to be universal behavior.
    public:
        std::shared_ptr&lt;MySingleInterface&gt;  createTheObject() override
        {
            std::shared_ptr&lt;MySingleInterface&gt;  instance = std::shared_ptr&lt;MySingleInterface&gt;(new MyDefaultSingleton());
            return instance;
        }
};


Example Test Singelton

class MyTestSingleton: public MySingleInterface
{
    int value;
    public:
    MyTestSingleton()
        : value(rand())
    {}
    public:
        virtual int doWork() override {return value;}        // Operation for testing.
};

class MyTestSingletonFactory: public MySingleFactoryInterface
{
    // This factory creates a new instance each time.
    // Can be useful for some types of test.
    public:
        std::shared_ptr&lt;MySingleInterface&gt;  createTheObject() override
        {
            return std::make_shared&lt;MyTestSingleton&gt;();
        }
};

class MyTestPersistantSingletonFactory: public MySingleFactoryInterface
{
    // As long as the code holds a shared pointer it will be re-used.
    // Useful if you want to create the singleton during "setUp()" and
    // destroy it during "tearDown()" you get a brand new singleton for
    // each individual test.
    public:
        std::shared_ptr&lt;MySingleInterface&gt;  createTheObject() override
        {
            // I leave the exercise of locking to you.
            static std::weak_ptr&lt;MySingleInterface&gt;     persist;
            auto result = persist.lock();
            if (!result)
            {
                result = std::make_shared&lt;MyTestSingleton&gt;();
                persist = result;
            }
            return result;
        }
};


Test Harness

int main()
{
    srand(0);

    // Incrementing results.
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";

    // Each result indapendant.
    MyTestSingletonFactory  testFactory;
    MySingletonFactory::setFactory(testFactory);
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    std::cout &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";


    MyTestPersistantSingletonFactory    persistantFactory;
    MySingletonFactory::setFactory(persistantFactory);
    {
        // As long as we hold a reference then
        // we should get the same result.
        std::shared_ptr&lt;MySingleInterface&gt; local = MySingletonFactory::getInstance();
        std::cout &lt;&lt; "L: " &lt;&lt; local-&gt;doWork() &lt;&lt; "\n";
        std::cout &lt;&lt; "L: " &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
        std::cout &lt;&lt; "L: " &lt;&lt; local-&gt;doWork() &lt;&lt; "\n";
        std::cout &lt;&lt; "L: " &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
    }
    // No local reference so we will create a new value.
    std::cout &lt;&lt; "N: " &lt;&lt; MySingletonFactory::getInstance()-&gt;doWork() &lt;&lt; "\n";
}


Output

&gt; ./a.out
0
1
2
3
4
5
6
7
8
520932930
28925691
822784415
890459872
L: 145532761
L: 145532761
L: 145532761
L: 145532761
N: 2132723841