#include <iostream> #include <memory> #include <mutex> class SingletonOld { static std::shared_ptr<SingletonOld> handle_; static std::mutex handle_mutex_; int data_ = 0; public: static auto create() { std::lock_guard<std::mutex> lock(handle_mutex_); if (handle_ == nullptr) { handle_.reset(new SingletonOld); // Using `make_shared` is error, as `SingletonOld` constructor is private // to `shared_ptr`, `allocator` and any class else. // handle_ = std::make_shared<SingletonOld>(); } return handle_; } int get_data() { return data_; } void set_data(int data) { data_ = data; } private: SingletonOld(const SingletonOld &) = delete; SingletonOld &operator=(const SingletonOld &) = delete; SingletonOld() {}; }; std::shared_ptr<SingletonOld> SingletonOld::handle_; std::mutex SingletonOld::handle_mutex_; class Singleton { int data_ = 0; public: static Singleton &create() { // 1. C++11: If control enters the declaration concurrently while the // variable is being initialized, the concurrent execution shall wait for // completion of the initialization. // 2. Lazy evaluation. static Singleton s; return s; } int get_data() { return data_; } void set_data(int data) { data_ = data; } private: Singleton(const Singleton &) = delete; Singleton &operator=(const Singleton &) = delete; Singleton() {} }; int main() { auto p = SingletonOld::create(); std::cout << p->get_data() << std::endl; // 0 p->set_data(1); auto q = p; std::cout << q->get_data() << std::endl; // 1 Singleton &s = Singleton::create(); Singleton &r = s; r.get_data(); std::cout << s.get_data() << std::endl; // 0 s.set_data(1); std::cout << r.get_data() << std::endl; // 1 return 0; }