IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Creation d'un singleton dynamique


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut Creation d'un singleton dynamique
    Bonjour à tous,

    Je souhaite créer une classe singleton avec un comportement un peu diffèrent du singleton classique. L'idée est qu'une instance de cette classe puisse être créée n'importe où et n'importe quand dans mon programme, puis éventuellement détruite et recréée ailleurs. Un objet de ce type se manipule comme n'importe quel autre objet (constructeur public,...), mais une tentative de création alors qu'une instance est déjà en cours lèverait une exception. Pour l'instant je suis parti sur une petite classe utilisée en variable static dans mon singleton servant à tester l'existence d'une instance:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    template< class T>
    class DynamicSingleton
    {
    	T * m_instance;
     
    public:
     
    	DynamicSingleton()
    		:m_instance(NULL)
    	{}
     
    	void NewInstance(T * instance)
    	{
    		if(m_instance)
    			throw std::exception("An object of this type is already available");
     
    		m_instance = instance;
    	}
     
    	void DestroyInstance()
    	{
    		m_instance = NULL;
    	}
     
    	T * Instance()
    	{
    		return m_instance;
    	}
    };
    et ma classe singleton:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class MonSingleton
    {
    	static DynamicSingleton<MonSingleton> m_singleton;
     
    public:
     
    	MonSingleton()
    	{
    		m_singleton.NewInstance(this);
    	}
     
    	~MonSingleton()
    	{
    		m_singleton.DestroyInstance();
    	}
     
    	static MonSingleton * Instance()
    	{
    		return m_singleton.Instance();
    	}
    };
    Du coup je me pose la question: s'agit-il d'un système bien foireux? Une énorme erreur en cours d'exécution me pend-elle au nez ? Et surtout, avez vous une idée pour faire ça proprement?

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 119
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Ça semble assez foireux, y a pas à dire. Fuite de mémoire? bah si l'utilisateur fait pas gaffe, y a en aura ( comme toujours ).

    Et puis, je pensais que ça:
    Ça serait static ( un peu comme dans un singleton, vu que vous parlez de singleton ).

    Pourquoi faire une exception, et non pas retourné l'objet ? ( plus comme le singleton )
    Ah ... tiens je me suis perdu entre singleton et celui dynamique
    Et en plus les deux boucles entre eux O_o ...
    Et puis le singleton ( non dynamique ) il devrait avoir un pointeur sur lui même et non juste une copie... enfin je crois ...
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Hello et merci pour ta reponse,
    Ça semble assez foireux, y a pas à dire
    On est assez d'accord sur le fond.
    Fuite de mémoire?
    Ça devrait tenir debout de ce coté. Tous les objets sont manipulés par shared_ptr, leur instanciation est également encapsulée dans un shared_ptr, donc la levée d'une exception dans le constructeur ne devrait pas poser de problèmes.
    Pourquoi faire une exception, et non pas retourné l'objet ? ( plus comme le singleton )
    Ah ... tiens je me suis perdu entre singleton et celui dynamique
    Et en plus les deux boucles entre eux O_o ...
    Et puis le singleton ( non dynamique ) il devrait avoir un pointeur sur lui même et non juste une copie
    Heu là je vois pas bien ton point. Il n'y a pas de copie, simplement ce singleton (appelons le singleton dynamique pour pas confondre avec le pattern) possède un pointeur static vers l'unique instance existante via le DynamicSingleton<> (qui vaut NULL s'il n'y en a pas). L'idée générale est que la classe MonSingleton puisse se comporter comme n'importe quelle autre classe (instanciation d'objets avec l'opérateur new, destruction avec delete, etc...) sauf que le constructeur va lever une exception si une instance existe déjà. En tout cas c'est le but que j'aimerais atteindre, avec ce système ou autre chose.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Pourquoi pas, tout simplement, quelque chose de fort proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Singleton
    {
        public:
            static Singleton & instance() // crée l'instance en cas de besoin
            {
                if(!inst_)
                    inst_ = new Singleton();
                return *inst_;
            }
            static void destroy() // détruit l'instance à l'envie
            {
                delete inst_;
                inst_ = NULL;
            }
            /*...*/
        private:
            Singleton(){}
            ~Singleton(){}
            static Singleton * inst_; 
    };
    // ne pas oublier de définir inst_ à NULL dans un fichier d'implémentation ;)
    qui pourrait parfaitement être utilisé sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void foo()
    {
        // j'ai besoin de mon singleton
        Singleton & s = Singleton::instance(); // il est créé en cas de besoin
        /*...*/
        // je n'en ai plus besoin, je peux le détruire
        Singleton::destroy();
    }
    En fait, ce n'est qu'une des manière classiquement envisagée de définir un singleton, non (même si on considère généralement qu'un singleton ne devrait jamais être détruit "a mano" )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Hello,

    Salut,

    Pourquoi pas, tout simplement, quelque chose de fort proche de
    Code :

    class Singleton
    {
    public:
    static Singleton & instance() // crée l'instance en cas de besoin
    {
    if(!inst_)
    inst_ = new Singleton();
    return *inst_;
    }
    static void destroy() // détruit l'instance à l'envie
    {
    delete inst_;
    inst_ = NULL;
    }
    /*...*/
    private:
    Singleton(){}
    ~Singleton(){}
    static Singleton * inst_;
    };
    // ne pas oublier de définir inst_ à NULL dans un fichier d'implémentation

    En fait, j'ai une contrainte supplémentaire dont je n'avais pas parlé: cet objet de type singleton est instancié via une factory (génération automatique d'objets depuis un fichier XML). Cette factory stock en interne une map de string->fonction renvoyant un IIoObject*(type de base des objets instanciables depuis un fichier XML). Mon singleton doit donc se comporter comme n'importe quel autre IIoObject, ce qui exclut les méthodes statiques de type Instance() qui créées l'objet au premier appel. C'est pour ca que j'étais parti sur la solution foireuse de mon premier post. Cela dit, je peut peut être modifier la fonction enregistrer dans ma factory (la même pour tous) uniquement pour mon singleton. Cela donnerait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T, typename U>
    boost::shared_ptr<T> CreateSingleton()
    {
        return boost::shared_ptr<T>(U::Instance());
    }
    au lieu de la fonction utilisée par tous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T, typename U>
    boost::shared_ptr<T> Create()
    {
        return boost::shared_ptr<T>(new U());
    }
    Pour les register dans la factory cela donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RegisterClass("MonSingleton", &CreateSingleton<IIoObject,MonSingleton>)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RegisterClass("MonSingleton", &Create<IIoObject,MonSingleton>)
    Ça me semble plus propre que le pseudo singleton dynamique initiale non?

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Alors, là, il y a un problème quelque part au niveau de ta conception...

    Soit, tu as besoin d'un singleton qui agit comme tel, soit tu as besoin d'un objet polymorphe instancié par une fabrique.

    Mais, généralement, les objets instanciables au travers de fabrique ne peuvent que très rapidement avoir une restriction d'unicité d'instance

    Ceci dit, le meilleur moyen de s'assurer qu'il n'existe qu'une seule instance d'un objet donné est encore... de faire en sorte qu'il n'y ait qu'un seul objet qui utilise cette unique instance comme membre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. [ActiveX] Creation d'un composant dynamique
    Par xv-mnt dans le forum MFC
    Réponses: 5
    Dernier message: 28/01/2006, 18h22
  2. creation de page web dynamique
    Par noussaENSI dans le forum Autres langages pour le Web
    Réponses: 2
    Dernier message: 15/12/2005, 13h20
  3. creation d'une fonction dynamiquement...
    Par bibile dans le forum Général Python
    Réponses: 2
    Dernier message: 04/08/2005, 10h38
  4. [syntaxe]Creation table avec nom dynamique
    Par ZuZu dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 23/09/2004, 18h01
  5. Creation d'une vue dynamique ?
    Par Simeans2004 dans le forum Administration
    Réponses: 5
    Dernier message: 01/07/2004, 15h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo