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

C++ Discussion :

Détruire un singleton automatiquement ?


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut Détruire un singleton automatiquement ?
    Bonjour,

    j'ai une classe CSingleton somme toute classique (c'est à dire avec une fonction GetInstance et une autre Kill). Dans mon programme, j'écrit par exemple:

    CExcel obj;
    Obj = CExcel::Get();


    et à la fin, je ne dois surtout pas oublier un petit CExcel::Kill();

    Oui mais voilà, je suis tête en l'air... Alors je me demandais s'il n'y a pas moyen, par hasard, de rajouter cela quelque part (dans un destructeur par exemple), de manière à ne plus à me préoccuper de cette ligne. Par exemple, à la fin du programme, l'objet "obj" (CExcel obj) est automatiquement libéré, et ~CExcel() est appelé. J'ai essayé d'ajouter Kill() dedans, mais c'est sans effet.

    Bref, comment peut on rendre automatique cet appel ?

    Merci

    Cordialement

  2. #2
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CExcel obj;
    Obj = CExcel::Get();
    A vérifier ... mais je crois que tu fais une copie de ton objet singleton CExcel.. ce qui ne devrait pas arrivé si ton constructeur par copie est privé.

    De plus, il n'y a pas de méthode générale pour détruire automatique un singleton seul. Il faut un système a part d'enregistrement de ton singleton et de destruction à la fin de l'application. Mais c'est un système à part du pattern singleton

  3. #3
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Là tu cherches quelque chose proche du RAII.
    Dans ton programme il n'y a pas une classe qui est instanciée au début et qui est détruite à la fin du programme ? Elle pourrait porter la responsabilité de ton Singleton et le détruire donc à sa propre destruction.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    static CExcel& CExcel::Get()
    {
        static CExcel instance;
        return instance;
    }
    Et écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CExcel& obj = CExcel::Get();
    Et non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CExcel obj;
    obj = CExcel::Get();
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CExcel obj = CExcel::Get();

  5. #5
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Un singleton, normalement, c'est un pointeur static :
    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
     
    class CExcel
    {
    public :
        static CExcel & Get( void )
        {
            if( instance == NULL )
            {
                instance = new CExcel();
            }
            return *instance;
        }
     
        static void Kill( void )
        {
            if( instance != NULL )
            {
                delete instance;
            }
        }
     
    private :
        CExcel(){}
     
        static CExcel * instance;
    };

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    L'implémentation proposée par loufoque est aussi très utilisée raptor

  7. #7
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Citation Envoyé par Alp Voir le message
    L'implémentation proposée par loufoque est aussi très utilisée raptor
    Oui, mais tout reste sur la stack ...

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Et surtout, si t'utilise pas le singleton, on se mange quand même une initialisation, qui peut être couteuse si l'objet est gros.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Et surtout, si t'utilise pas le singleton, on se mange quand même une initialisation, qui peut être couteuse si l'objet est gros.
    Non, c'est initialisé à la première utilisation de la fonction.

    Puis je crois vraiment pas que c'est stocké dans la pile, il faut que je retrouve la référence.
    Si c'était stocké sur la pile, alors ce serait dépilé après, et ça serait illogique.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Vous avez raison, j'ai écrit un peu vite. En fait, mon code est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    CExcel*  Obj;
    Obj = CExcel::Get()
    avec ma classe template :

    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
    30
    31
    32
    33
    34
    35
     
    template<class T>
    class CSingleton
    {
    private:
    	static T*	m_Instance;
     
    protected:
    	CSingleton(){};
    	~CSingleton(){};
     
    public:
     
    	static T* Get()
    	{
    		if( !m_Instance )
    			m_Instance = new T;
     
    		return m_Instance;
    	}
     
    	static bool Kill()
    	{
    		if( !m_Instance )
    			return false;
     
    		delete m_Instance;
     
    		return true;
    	}
     
    };
     
    template <class T>
    T *CSingleton<T>::m_Instance = NULL;
    dont dérive CExcel. Puisqu'on en parle, j'ai une petite question : quelle différence y'a-t-il entre écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CExcel& obj = CExcel::Get()
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CExcel* obj = CExcel::Get()
    Ok, l'un est un pointeur et l'autre une adresse, mais en pratique ?


    merci

  11. #11
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Citation Envoyé par delire8 Voir le message
    Ok, l'un est un pointeur et l'autre une adresse, mais en pratique ?
    Faux ... l'un est un pointeur (==adresse) et l'autre une référence.

    Il est toujours plus intéressant de passer par référence car plutôt que d'accéder à chaque accès à la mémoire, tu travaille directement sur l'objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CExcel * obj;
    obj->blabla1();  // 1er accès mémoire
    obj->blabla2(); // 2e accès a la memoire
     
    // et moins bien que 
     
    CExcel & obj;
    obj.blabla1();  // l'objet est connu ...
    obj.blabla2();

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Bien compris ! Le pire étant que je pensais ne faire qu'un seul accès mémoire en passant par les pointeurs... autant dire que ta remarque me fait prendre conscience que j'ai des updates à faire...

    merci

    cordialement

  13. #13
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    Citation Envoyé par delire8 Voir le message
    Bien compris ! Le pire étant que je pensais ne faire qu'un seul accès mémoire en passant par les pointeurs... autant dire que ta remarque me fait prendre conscience que j'ai des updates à faire...

    merci

    cordialement
    La règle général est de toujours préférer les références aux pointeurs..

    EDIT : ... pour les transferts de données ...

  14. #14
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    La règle c'est de n'utiliser des pointeurs que quand on y est vraiment obligés. Et encore là on peut écrire du code semblable à un code utilisant des références grâce aux smart pointers.

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par HanLee Voir le message
    Puis je crois vraiment pas que c'est stocké dans la pile, il faut que je retrouve la référence.
    Les variables statiques de fonction ne sont pas stockées dans la pile.

    Citation Envoyé par raptor70 Voir le message
    Il est toujours plus intéressant de passer par référence car plutôt que d'accéder à chaque accès à la mémoire,
    Mutatis mutandis, le code généré pour l'utilisation d'une référence a de bonnes chances d'être le même que celui généré pour l'utilisation d'un pointeur (il y a des cas où ce n'est pas le cas, mais je ne vais pas m'étendre dessus ici).

    Citation Envoyé par raptor70
    La règle général est de toujours préférer les références aux pointeurs.
    Citation Envoyé par Al
    La règle c'est de n'utiliser des pointeurs que quand on y est vraiment obligés.
    Si on exclus les cas où on n'a pas le choix (surcharge d'opérateurs, possibilité d'une valeur NULL), le choix résulte à mon avis plus d'une convention de codage que de règles. Les extrêmes (utiliser toujours des pointeurs ou des références sauf cas où on n'a pas le choix) sont à mon avis mal inspirés. Comme pour le moment l'extrême pro-référence est celui favorisé, je trouve totalement absurde de faire quelque part:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    X& x = new X();
    ...
    delete  &x;
    J'ai déjà écrit à ce sujet. Il faudrait que je prenne le temps d'étendre mes explications aux cas autres que le passage de paramètres.

  16. #16
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Je pense toutefois qu'il vaut mieux mettre en avant, à l'opposé de beaucoup de cours, les références du C++. Beaucoup de situations obligent des pointeurs, mais on s'en sort désormais très facilement avec, même les "débutants", car de bons outils sont fournis.

    @Jean-Marc : une petite Question/Réponse sur le sujet pourrait être très intéressante. Tu sembles avoir de quoi dire sur le sujet

  17. #17
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Alp Voir le message
    @Jean-Marc : une petite Question/Réponse sur le sujet pourrait être très intéressante. Tu sembles avoir de quoi dire sur le sujet
    J'aime pas les réponses définitives et courtes à ce genre de question.

    La question fondamentale est "comment exprimer clairement ses intentions?" et elle est un peu vaste. Elle est compliquée par le fait que les langages de programmation sont généralement des langages répondant à la question "comment?" et non "quoi?" mitigés par quelques provisions permettant des variations (comportement indéfini, règles "as-if", ...).

    Une syntaxe donnée devrait avoir une intention et chaque intention sa syntaxe. Dans le cas du C++ et des sémantiques de références, on a deux syntaxes particulières (les pointeurs bruts et les références) et la possibilité de se construire autant de concepts que l'on veut (les pointeurs intelligents). Il faut donc isoler des intentions suffisemment généralistes et les mettre en correspondance avec ce qui est disponible en respectant les contraintes posées par le langage.

    Pour le sens que je donne aux références du C++, c'est d'être un alias localisé, on arrive donc à mes règles opératives (et admettant des exceptions) sont
    - ne jamais devoir utiliser l'opérateur &;
    - toujours pouvoir passer une variable locale quand on demande une référence
    Je remarque aussi qu'en pratique je n'utilise jamais de référence pour des objets qui ne sont pas instantiables sur la pile.

  18. #18
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ma solution est la meilleure, c'est tout, y'a pas à chercher plus loin.
    D'après GCC et C++0x, elle est aussi thread-safe...

  19. #19
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ma solution est la meilleure, c'est tout
    Bof..., elle ne permet pas de gérer le cas où le type le plus dérivé du singleton est déterminé dynamiquement et il n'y a pas moyen de contrôler l'ordre de destruction.

  20. #20
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ma solution est la meilleure, c'est tout, y'a pas à chercher plus loin.
    D'après GCC et C++0x, elle est aussi thread-safe...
    elle SERA, alors. car sur les compilos actuels a la norme actuelle, tu l'as dans l'os.

Discussions similaires

  1. Réponses: 3
    Dernier message: 12/01/2012, 13h51
  2. Réponses: 2
    Dernier message: 17/03/2008, 10h58
  3. Génerer automatiquement plusieurs fichier .doc
    Par brunovitch dans le forum QuickReport
    Réponses: 3
    Dernier message: 09/07/2002, 08h19
  4. Re-dimensionnement automatique de composants
    Par ludo_7 dans le forum C++Builder
    Réponses: 10
    Dernier message: 16/05/2002, 16h35

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