2010-04-07 3 views
3

Peut-on hériter d'une classe singleton. Si oui, alors comment pouvons-nous le faire?C++ - Classe singleton

** EDIT: *** Je veux dire que si nous avons une classe qui utilise design pattern singleton, alors il peut être héritée *

+6

Oui. classe A: public Singleton {...}; –

+3

Je pense que Neil essaie de dire que nous avons besoin de plus d'informations. Quelque chose comme: «J'ai un singleton qui ressemble à ceci ... et je veux en hériter pour qu'il fasse ce qui suit ...» – tloach

+1

Il n'y a pas de «Singleton» pour poser des questions, ça dépend de votre la mise en œuvre du modèle. Si vous avez même besoin du motif. (Indice: vous n'avez pas). http: // jalf.dk/blog/2010/03/singletons-resolution-problems-you-didnt-know-you-never-had-since-1995/ – GManNickG

Répondre

1

cours Singleton sont destinés à être héritée. Le modèle singleton n'a pas beaucoup de valeur sans héritage.

  1. Définir une classe de base essentiellement abstraite avec une fonction membre instance() statique.
  2. Définissez une ou plusieurs classes dérivées qui implémentent l'interface de base.
  3. Implémentez instance() pour décider à l'exécution la classe à instancier et à renvoyer. Singleton a un constructeur privé, donc l'héritage n'est pas possible.
+4

Aucun de mes singletons n'est hérité, mais ils semblent très utiles. Ne confondez pas un modèle avec une implémentation. –

+0

Certains diront que ce que vous décrivez est vraiment une combinaison de Singleton et Factory, et pas seulement de Singleton. Mais je suis d'accord que Singleton sans usine est généralement un anti-pattern. –

+0

Je suis d'accord avec Kristopher. Ce n'est techniquement pas le modèle de Singelton. Mais là encore c'est comme ça que je le fais parce que sans la possibilité d'instancier (ou enregistrer) différents singeltons dans différentes situations (1 par contexte d'application [app/test etc]) il devient impossible (ou très difficile) de tester le système. –

4

en plus singleton a des méthodes statiques pour instancier un membre d'instance privée et puisque vous ne pouvez pas remplacer les méthodes statiques, il serait inutile d'hériter de singleton.

+0

Singleton ont normalement un constructeur protégé. –

+4

Nous n'avons pas le même singleton alors. Si protégé, vous n'avez aucune garantie d'unicité. –

+0

@Marcelo: ce que moi, Matthieu et d'autres appelons 'singleton' est la classe qui n'a qu'une seule instance, et vous appelez 'Singleton' la base abstraite qui a le code de support pour les singletons. Je pense qu'il serait plus approprié de l'appeler 'SingletonBase' puisque cette classe n'est pas le singleton lui-même - le singleton est la classe concrète. –

3

Cela dépend de la façon dont est votre implémentation pour le motif de conception. La forme la plus simple est de faire une classe comme ceci:

class MySingleton 
{ 
    public: 
     static MySingleton &getInstance() 
     { 
      static MySingleton instance;    
      return instance; 
     } 
    private: 
     MySingleton(); 
     ~MySingleton(); 
}; 

Dans ce cas, il ne peut pas être héritée parce que la classe dérivée n'a pas accès à son constructeur. Vous pouvez protéger le constructeur, mais cela permettra à d'autres classes dérivées d'être non-singleton à volonté, ce qui peut être désordonné du point de vue de la conception. Mais généralement, cette forme simple n'est pas la meilleure façon d'implémenter des singletons car vous n'avez pas beaucoup de contrôle sur sa durée de vie et il est difficile de gérer correctement les dépendances entre singletons - sans parler des problèmes de multithreading. Le livre Moderne C++ Design (http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315/ref=sr_1_1?ie=UTF8&s=books&qid=1270652521), entre autres, a de meilleures implémentations; ils sont basés sur un modèle et l'instanciation du modèle est ce qui fait de l'objet un singleton (et son paramètre est la classe qui sera créée en singleton). Cela rend plus facile de faire ce que vous voulez, puisque le 'singleton-ness' est détaché de la classe elle-même. Mais néanmoins je pense que vous auriez besoin d'une politique (éventuellement imposée par le code) pour éviter qu'une classe dérivée d'un singleton soit non-singleton, ce qui est difficile à mettre en œuvre. Ma recommandation serait d'avoir des classes de base abstraites comme ancêtres pour vos singletons, et de mettre le comportement commom en eux, pas dans le singleton lui-même, et avoir le singleton toujours comme la classe 'finale' (empruntant ce sens de Java).

+0

Ce lien est très utile aussi: http://www.yolinux.com/TUTORIALS/C++Singleton.html – jhtong

0

J'ai une classe Singleton dont j'hérite dans de nombreux cas.

Voici le Singleton:

template <class Target> 
class Singleton_Shared_Ptr 
{ 
    //--------------------------------------------------------------------- 
    // Public Constructors & Destructors 
    //--------------------------------------------------------------------- 
    public: 
    //! Destructor. 
    virtual   ~Singleton_Shared_Ptr(); 

    //--------------------------------------------------------------------- 
    // Public methods 
    //--------------------------------------------------------------------- 
    public: 
    //! Returns a pointer to the instance. 
    static boost::shared_ptr<Target> ptr(void); 

    //! Returns a reference to the instance. 
    static Target &      ref(void); 

    //--------------------------------------------------------------------- 
    // Protected methods 
    //--------------------------------------------------------------------- 
    protected: 
    //! Default constructor. 
        Singleton_Shared_Ptr(); 

    //--------------------------------------------------------------------- 
    // Private methods 
    //--------------------------------------------------------------------- 
    private: 
    //! Copy constructor, not implemented. 
    /*! The copy constructor is declared so that the compiler will not 
     * automatically generate one. 
     */ 
        Singleton_Shared_Ptr(const Singleton_Shared_Ptr& s); 

    //! Assignment operator, declared but not defined. 
    /*! The assignment operator is declared so that the compiler will not 
     * automatically generate one. 
     */ 
    Singleton_Shared_Ptr&  operator=(const Singleton_Shared_Ptr& s); 

    //--------------------------------------------------------------------- 
    // Private members 
    //--------------------------------------------------------------------- 
    private: 
    static wxMutex      m_instance_mutex; 
}; 

template<class Target> 
wxMutex      Singleton_Shared_Ptr<Target>::m_instance_mutex; 

//------------------------------------------------------------------------- 
// Singleton_Shared_Ptr Constructors & Destructors 
//------------------------------------------------------------------------- 
template <class Target> 
inline 
Singleton_Shared_Ptr<Target> :: 
Singleton_Shared_Ptr() 
{ 
} 


template <class Target> 
inline 
Singleton_Shared_Ptr<Target> :: 
~Singleton_Shared_Ptr() 
{ 
} 


//------------------------------------------------------------------------- 
// Singleton_Shared_Ptr methods in alphabetical order 
//------------------------------------------------------------------------- 
template <class Target> 
boost::shared_ptr<Target> 
Singleton_Shared_Ptr<Target> :: 
ptr(void) 
{ 
    static boost::shared_ptr<Target> p_instance; 
    if (p_instance.get() == NULL) 
    { 
     wxMutexLocker lock(m_instance_mutex); 
     if (!p_instance) 
     { 
      p_instance.reset(new Target); 
     } 
    } 
    return p_instance; 
} 


template <class Target> 
Target & 
Singleton_Shared_Ptr<Target> :: 
ref(void) 
{ 
    return *(ptr()); 
} 

Voici l'utilisation du singleton:

class Manager 
    : public Singleton_Shared_Ptr<Manager> 
{ 
    //--------------------------------------------------------------------- 
    // Friends 
    //--------------------------------------------------------------------- 
    friend class Common::Singleton_Shared_Ptr<Manager>; 

    //--------------------------------------------------------------------- 
    // Public Constructors and Destructors 
    //--------------------------------------------------------------------- 
    public: 
    //! destructor 
    virtual     ~Manager(); 

    //--------------------------------------------------------------------- 
    // Protected Methods 
    //--------------------------------------------------------------------- 
    protected: 
    //! Constructor 
           Manager(); 

    //! Copy constructor -- declared but not implemented. 
           Manager(const Manager& m); 

    //! Assignment operator -- declared but not implemented. 
    Manager&     operator= (const Manager& m); 
};