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 :

Destructeur privé


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut Destructeur privé
    Bonjour,

    J'essaie d'implementer la classe singleton avec un desctructeur privé, sauf qu'à la compilation j'ai cette erreur (GlobalClass::~GlobalClass'*: impossible d'accéder à private membre déclaré(e) dans la classe 'GlobalClass) dans ligne :
    alors que la ligne ne pose aucun problème.
    Quelqu'un peut m'expliquer?
    Rq: Le programme compile qd le destucteur est publique.
    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
    36
    37
    38
    39
    40
    41
    class GlobalClass
    {
        int m_value;
        static GlobalClass *s_instance;
        GlobalClass(int v = 0)
        {
            m_value = v;
    		cout<<" construct singleton"<<endl;
        }
    	~GlobalClass(){}
      public:
        int get_value()
        {
            return m_value;
        }
        void set_value(int v)
        {
            m_value = v;
        }
        static GlobalClass *instance()
        {
            if (!s_instance)
              s_instance = new GlobalClass;
            return s_instance;
        }
    };
    
    // Allocating and initializing GlobalClass's
    // static data member.  The pointer is being
    // allocated - not the object inself.
    GlobalClass *GlobalClass::s_instance = NULL;
    
    int main()
    {
    GlobalClass *p1=GlobalClass::instance();
    	GlobalClass sing=*p1; // le problème est là
    	GlobalClass *p2=p1->instance();
    	GlobalClass &ref=*p1;
    	p1->set_value(3);
    return 0;
    }

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Ton code est tres bizzard
    regarde ici pour faire un singleton en C++: http://come-david.developpez.com/tut...Singleton#LIII

    dans ton main l'utilisation de ton singleton est aussi tres bizarre:
    toutes tes référence et pointeurs sont inutiles.
    tu devrais avoir quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main()
    {
        GlobalClass::instance().set_value(3);
        return 0;
    }

  3. #3
    Membre éclairé Avatar de thoratou
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 57
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    GlobalClass sing=*p1;
    Ce code utilise le constructeur par recopie, qui n'est pas redefinie dans ta classe, et qui utilise donc le constructeur de copie par defaut, qui est public.

    Le probleme est donc que tu peux bien copie ton instance, mais pas la detruire, puis que destructeur est prive.

    Hors tu appelles automatiquement le destructeur a la fin du main, puisque sing n'est pas alloue dynamiquement mais dans la pile.

    Mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    GlobalClass &sing=*p1;
    resoudra ton probleme

    Edit :

    Oui j'oubliais juste, tu n'as pas de methode permettant de destruire ton singleton, et tu auras donc des memory leaks. Tu as 2 solutions simple :

    Soit tu ajoute la methode, pour la detruire, et a ce moment-la tu peux recreee ton instance a tout moment,

    Soit tu met simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static GlobalClass _instance;
    dans ton singleton, qui sera alors automatiquement detruit a la fin du programme

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    On pourrait mettre à jour cet article sinon avec:

    - Une utilisation thread-safe: ne pas faire de lazy-init, mais une init genre dans le main avant le lancement des threads

    - Il y a une solution avec une variable statique et un appel à boost::call_once qui permet de faire du lazy-init thread safe

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Ceci dit faire un copie avec un DP singleton ... c'est original. C'est un multi-ton alors
    Ton singleton devrait être non copiable : F.A.Q. Comment rendre une classe non copiable ?

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    On pourrait mettre à jour cet article sinon avec:

    - Une utilisation thread-safe: ne pas faire de lazy-init, mais une init genre dans le main avant le lancement des threads

    - Il y a une solution avec une variable statique et un appel à boost::call_once qui permet de faire du lazy-init thread safe
    JE ne suis pas certain de ce que tu appelles lazy-init, mais le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Singleton &Singleton::instance()
    {
      static Singleton theInstance;
      return theInstance;
    }
    est thread-safe, selon la définition C++0x du langage, et appelle les destructeurs à la fin du programme. Seul problème : Certains compilateurs (visual C++, par exemple) ne respectent pas (encore) cette règle.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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