I'm wondering whats the best way to make a safe singleton that needs to be called with an initialise() with arguments, before it will return a valid object using the getInstance() call. E.g.
#include <memory>
#include <mutex>
#include <atomic>
class MySingleton {
public:
static void initialise(const std::string& myName) {
std::lock_guard<std::mutex> lock(MySingleton::m_initMutex);
if (!MySingleton::m_initialised) {
m_self = std::shared_ptr<MySingleton>(new MySingleton(myName));
MySingleton::m_initialised = true;
}
}
static std::shared_ptr<MySingleton> getInstance(){
if ( MySingleton::m_initialised.load()) {
return m_self;
} else {
return nullptr;
}
}
MySingleton(const MySingleton&) = delete;
MySingleton& operator=(const MySingleton&) = delete;
private:
MySingleton(const std::string myName) : m_myName(myName) {}
static std::shared_ptr<MySingleton> m_self;
static std::mutex m_initMutex;
static std::atomic<bool> m_initialised;
std::string m_myName;
};
std::shared_ptr<MySingleton> MySingleton::m_self{nullptr};
std::atomic<bool> MySingleton::m_initialised{false};
std::mutex MySingleton::m_initMutex;
Is there anything dangerous/not thread safe about this? Is there a cleaner/better way to approach this?