Question

In Java I can create a Singleton like this (as long as it doesn't throw as exception):

private static Singleton m_this = new Singleton();

This is very convenient because it's inherently thread safe.

Can I do something similar in C++?

Was it helpful?

Solution

One way of making a singleton with thread-safe initialization, guaranteed by the standard as of C++11. is:

class SomeSingleton {
  public:
    static SomeSingleton& instance() {
      static SomeSingleton instance_;
      return instance_;
    }

  private:
  SomeSingleton() {
    ...
  }
};

This is thread-safe, because local static variable initialization is thread-safe in C++11. The relevant standard document, N3485, says in section 6.7.4:

such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

with footnote:

The implementation must not introduce any deadlock around execution of the initializer.

You can abstract into a nice template base class with CRTP:

//Singleton template definition
template <typename TDerived>
class Singleton {
  static_assert(is_base_of<Singleton, TDerived>::value, "Singleton: unexpected Derived template parameter");
  public:
    static TDerived& instance() {
      static TDerived instance_;
      return instance_;
    }

  protected:
  Singleton() {
  }
};

// SomeSingleton definition, using the Singleton template
class SomeSingleton : public Singleton<SomeSingleton> {
  ...
};

OTHER TIPS

If by Singleton, you mean a real singleton (which I'm not sure is the same you gave an example of, because you still could create a second Singleton instance and assign it to a different variable), the answer is yes. You can create a singleton object using the factory pattern.

class factory;
class singleton{
   singleton(){}; // private constructor
   friend class factory;
};

class factory{
   private:
      static std::shared_ptr<singleton> object;

   public:
      static singleton& getSingleton(){
         if(object)
            return *object;
         object = new singleton;
         return *object;
      }
};

Instead of making a dedicated factory class, you could make getSingleton a static member function of singleton itself too. Just remember to make the constructor private, so the user can't create multiple copies.

Also, on top of answer given by Paweł Stawarz, I would add that copy constructor, move constructor (C++11), overloaded assignment operator and destructor should be private too.

class singleton{
   singleton(){}; // private constructor
   ~singleton(){}; // private destructor
   singleton(const singleton &src){}; // private copy constructor
   singleton(const singleton&& src){}; // private move constructor for C++11
   singleton& operator = (const singleton& src){return *this;} // private = operator
   friend class factory;
};

Being private, copy constructor, move constructor (C++11), overloaded assignment operator and destructor cannot be called from outside to clone an existing copy and also to destroy a copy just created.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top