Septagram
Septagram

Reputation: 9785

C++: Templates and the singleton pattern

It happens so that I have a need of the infamous singleton pattern. Better yet, it happens so that I have a need of infamous C++ templates in combination with that pattern. So, what troubles me is this:

template <class T>
class PDatabaseTable
{
    ...

    static PDatabaseTable <T> & instance()
    {
        static PDatabaseTable <T> singleton;
        return singleton;
    }

    ...
};

This is a typical way to implement a singleton that's supposed to be created on the first use. Now, here we have a static variable singleton. Since the instance() function may be called from several different modules, the question is: will there be only one instance of the object for any given type T, or will every module instantiate its very own singleton?

Upvotes: 7

Views: 7378

Answers (4)

jessn
jessn

Reputation: 11

You CAN move the init of the static outside of the class body, and this is also possible for the static function.

template <typename T>
class Singleton
{
public:
  static Singleton<T>* Singleton::getInstance();
  T* getMember() { member_; }
protected:
  Singleton() { member_ = new T; }
  ~Singleton() { if (singleton_) delete member_; }
private:
  static Singleton<T>* singleton_;
  T* member_;
};
template <typename T>
Singleton<T>* Singleton<T>::getInstance()
{
  if (NULL == singleton_) singleton_ = new Singleton;
  return singleton_;
}
template <typename T>
Singleton<T>* Singleton<T>::singleton_ = NULL;

Upvotes: 1

O.C.
O.C.

Reputation: 6829

Your singleton is called Meyers Singleton and you can find an explanation about thread safety of this singleton type in Static locals and threadsafety in g++ article which nicely explains how static local variables are thread-safe to create.

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254621

There will only be one instance for each type T, just as, if it weren't a template, there would only be one instance.

The function is inline, meaning that although it can be defined in multiple compilation units, after linking there will be only one version of it, and only one instance of any local static objects.

Upvotes: 5

iammilind
iammilind

Reputation: 70030

Definitely there will be only one instance.

I am just wondering why can't you move that static object out of function to the class body ?

template <class T>
class PDatabaseTable
{
  static PDatabaseTable <T> singleton;
  static PDatabaseTable <T> & instance()
  {
    return singleton;
  }
};
template<class T>
PDatabaseTable<T> PDatabaseTable<T>::singleton;

Upvotes: 1

Related Questions