c++singletonatomicrvo

Is Singleton object returned through shared_ptr thread-safe?


I was reading the answers to the question. C++ Singleton design pattern

One of the answer suggested to use shared_ptr to guarantee the lifetime when multiple static objects access the singleton object. I noticed that shared_ptr here is constructed using new and is returned by value.

Is using new for shared_ptr construction atomic/thread_safe?

My second confusion is regarding RVO. I tried creating two singleton objects in my implementation.

The shared_ptr shows three _Uses and one _Weak. I expected _Uses count to be two. Optimization is full on Visual Studio 15.5.6. Is RVO not functioning here?

class Singleton
{
public:
    Singleton(Singleton const&) = delete;
    Singleton& operator=(Singleton const&) = delete;

static std::shared_ptr<Singleton> instance()
{
    static std::shared_ptr<Singleton> s{new Singleton};
    return s;
}

    ~Singleton() {}
private:
    Singleton() {}
};

int main()
{
     std::shared_ptr<Singleton> obj1 = Singleton::instance();
     std::shared_ptr<Singleton> obj2 = Singleton::instance();
     return 0;
}

Solution

  • Is using new for shared_ptr construction atomic/thread_safe?

    Yes, the creation of the shared_ptr is thread safe because static initializations are thread-safe (see also this question)

    The shared_ptr shows three _Uses and one _Weak. I expected _Uses count to be two. Optimization is full on Visual Studio 15.5.6. Is RVO not functioning here?

    You have a use count of three, because the shared_ptr is declared static, which means when it is initialized, the object is created and thus the use count is increased by one (+2 for the two shared_ptr in the main). This use count is only decreased again, when the static shared_ptr is destroyed, and this happens when the programm terminates.