Choix du pattern de Singleton [Résolu]

Messages postés
246
Date d'inscription
dimanche 2 juin 2002
Statut
Membre
Dernière intervention
11 septembre 2016
- - Dernière réponse : cptpingu
Messages postés
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
- 15 juil. 2013 à 12:38
Bonjour,

Je vais bientôt passer des entretiens en C++ donc je m'entraine un peu.
En ce moment, je révise le pattern Singleton.

La plupart du temps, j'ai l'impression que le singleton est implémenté comme ceci:

class Singleton
{
private:
   [...]
public:
   static Singleton* getInstance()
   {
      if (!_instance) {
         Lock();
         if (!_instance)
            _instance = new Singleton;
      }
      return _instance;
   }
private:
   static Singleton* _instance;
};
Singleton* Singleton::_instance = NULL;


Pourtant, le singleton de Meyers semble beaucoup plus simple:

class Singleton:
{
private:
   [...]
public:
   static Singleton& getInstance()
   {
      static Singleton& _instance;
      return instance;
   }
};


Et j'ai l'impression que les deux codes sont à peu près équivalent. Sur certains compilateurs, le second code serait thread-safe.

Du coup, quel intérêt à utiliser le premier code ?
Ca me paraît plus long à écrire, et moins propre..

Cordialement,
Afficher la suite 

1 réponse

Messages postés
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
85
0
Merci
Bonjour.

Le premier code est, à mon sens, bien moins élégant. Les deux codes sont équivalents, mais la deuxième écriture est plus intelligente puisqu'elle permet, par nature, d'avoir directement certaines propriétés (comme être thread-safe, ou d'éviter de gérer manuellement une allocation).

Une forme que j'aime bien utiliser est la suivante:

template <typename T>
class Singleton /* : public boost::noncopyable */
{
public:
  /** Retrives the instance. */
  static T& instance();
};


template <typename T>
T&
Singleton<T>::instance()
{
  static T _instance;
  return _instance;
}


Ainsi, il est aisé de transformer une classe quelconque en singleton, par un simple héritage.
class Toto : public Singleton<Toto>
{
private:
  Toto() {}

public:
  int _a;
};

int main()
{
  Toto::instance()._a = 12;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu