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 :

Utilisation d'un objet sans initialisation


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 560
    Points : 71
    Points
    71
    Par défaut Utilisation d'un objet sans initialisation
    Bonjour,

    Je souhaiterais créer une classe Toto et pouvoir l'utiliser de cette facon: Toto::moninstance(param).

    Je ne sais plus comment s'appele ce mode d'utilisation d'une classe.

    Quelqu'un pourrait-il me rafraichir la mémoire?

    D'avance merci.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Tu veux parler d'une méthode statique?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Comme l'a dit Medinoc, c'est une methode static. Cependant il est relativement rare de s'en servir comme ca s'il n'y a pas un but particulier. Par-exemple, on pourrait tres bien tomber sur une classe gerant un personnage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Perso {
    public:
      static Wizard create_wizard();
      static Warrior create_warrior();
    }
    Apres rien ne t'empeche de creer une classe Wizard et une classe Warrior qui heriteront toutes les deux de Perso. Cependant, les methodes statiques me semblent assez peu adaptees a ce genre de cas. J'ai pour habitude de plutot m'en servir lorsque je ne veux qu'une seule instance d'un objet (on appelle ca un singleton au cas ou ce serait ce que tu cherches). Du coup son constructeur est private et le seul moyen de le creer est de passer par une methode statique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Object {
    public:
       static Object *get_instance() {
         static Object *o(0);
         if (!o) {
           o = new Object;
         }
         return o;
       }
     
    private:
       Object();
    }

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 560
    Points : 71
    Points
    71
    Par défaut
    Cool merci c'est exactement ce que je cherchais.

  5. #5
    Membre actif
    Inscrit en
    Mai 2012
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2012
    Messages : 65
    Points : 282
    Points
    282
    Par défaut
    Alors attention à la version du singleton d'imperio, car elle crée une fuite de mémoire, la manière propre de créer un singleton est comme ceci :

    version avec référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Object {
    public:
       static Object & get_instance() {
         static Object instance;
         return instance;
       }
     
    private:
       Object();
    }
    version avec pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Object {
    public:
       static Object * get_instance() {
         static Object instance;
         return &instance;
       }
     
    private:
       Object();
    }
    Les deux versions sont équivalentes.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par Danny-k Voir le message
    Alors attention à la version du singleton d'imperio, car elle crée une fuite de mémoire
    Avec un pointeur effectivement, ça va "fuiter" mais à la fermeture du programme la mémoire va être libérée.
    Sans pointeur, l'objet est détruit et la mémoire libérée mais cela se fait à la fin du programme ...
    Donc la "fuite de mémoire" on s'en fout un peu dans ce cas là, que l'on alloue dynamiquement ou pas la zone de mémoire est libérée à la fin.

    Par contre, si le destructeur doit faire autre chose que libérer des ressources, là ça devient important, et c'est là que la version "sans pointeur" est plus safe et adaptée.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Le standard garantit-il que la variable locale static est construite lors du premier appel à la fonction, et pas avant?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre actif
    Inscrit en
    Mai 2012
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2012
    Messages : 65
    Points : 282
    Points
    282
    Par défaut
    Citation Envoyé par the Hound Voir le message
    Avec un pointeur effectivement, ça va "fuiter" mais à la fermeture du programme la mémoire va être libérée.
    Sans pointeur, l'objet est détruit et la mémoire libérée mais cela se fait à la fin du programme ...
    Donc la "fuite de mémoire" on s'en fout un peu dans ce cas là, que l'on alloue dynamiquement ou pas la zone de mémoire est libérée à la fin.

    Par contre, si le destructeur doit faire autre chose que libérer des ressources, là ça devient important, et c'est là que la version "sans pointeur" est plus safe et adaptée.
    Ton OS va libérer la mémoire à la fin mais il n'empêche que ça reste une fuite de mémoire, pour ma part au boulot, on a une politique zero memory leak (on livre des lib), et c'est typiquement le cas où je ne pouvais pas me permettre d'avoir un memory leak.

    De toute façon il est meilleur de créer un singleton de cette façon, ça évitera beaucoup de problèmes, et c'est une bonne pratique à prendre.

  9. #9
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le standard garantit-il que la variable locale static est construite lors du premier appel à la fonction, et pas avant?
    Oui. Par contre, en cas d'appel multithread à cette fonction, le standard garanti bien que la variable n'est construite qu'une fois, mais certains compilos (= visual C++) ne respectent pas encore ce point.
    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.

  10. #10
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    L'exemple que j'ai fourni etait quelque chose de simplifie, rien n'empeche de faire appel a atexit pour bien nettoyer la memoire (ou autre methode). Cependant il est vrai qu'il est plus simple de ne pas s'encombrer d'un pointeur et ca a en plus l'avantage d'appeler le destructeur automatiquement.

  11. #11
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Petite précision : ce n'est pas parce qu'on veut utiliser static, qu'on veut faire un singleton... (même si le nom de la fonction semble suggérer ça).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class toto
    {
    public:
     
    	static void moninstance()
    	{
    		std::cout << "toto::moninstance()" << std::endl;
    	}
    };
    Dans ce contexte, static permettra d'indiquer que la fonction moninstance dépendra de la classe et pas d'un objet de la classe.
    static a une autre utilité qu'il faut utiliser avec précaution car il s'agit plus ou moins d'une variable globale :
    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
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++11 -pedantic -fopenmp main.cpp -o main && ./main
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++98 -pedantic -fopenmp main.cpp -o main && ./main
     
    #include <iostream>
    #include <string>
     
     
    void f()
    {
    	static int i = 0;
     
    	++i;
    	std::cout << i << std::endl;
    }
     
     
    int main()
    {
    	f(); // 1
    	f(); // 2
    	f(); // 3
     
    	return 0;
    }
    Une fois c'est deux utilisations combinées, on peut faire quelque chose qui s'apparente à un singleton.
    Pour le singleton, la première solution de Danny-k est la plus adaptée en C++11.

  12. #12
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par Danny-k Voir le message
    Ton OS va libérer la mémoire à la fin mais il n'empêche que ça reste une fuite de mémoire, pour ma part au boulot, on a une politique zero memory leak (on livre des lib), et c'est typiquement le cas où je ne pouvais pas me permettre d'avoir un memory leak.

    De toute façon il est meilleur de créer un singleton de cette façon, ça évitera beaucoup de problèmes, et c'est une bonne pratique à prendre.
    Je suis d'accord, il faut toujours faire en sorte qu'il n'y ait jamais de memory leak, ne serait-ce que pour des raisons de concepts ou de sécurité.
    Mais dans ce cas là en particulier, techniquement, ça ne change pas grand-chose, sauf si comme je l'ai dit le destructeur de la classe fait autre chose que libérer des ressources.

    black_hole, ton but est d'avoir une seule instance de la classe dans tout le programme, ou de pouvoir construire une quantité indéfinie d'objets via une méthode statique ?

Discussions similaires

  1. Réponses: 10
    Dernier message: 22/07/2014, 13h55
  2. serialiser un objet sans utiliser de bibliothèque externe
    Par Jérémy Lefevre dans le forum Langage
    Réponses: 2
    Dernier message: 11/04/2014, 17h02
  3. Réponses: 6
    Dernier message: 18/11/2012, 15h01
  4. Réponses: 2
    Dernier message: 30/08/2011, 23h40
  5. Copier un objet sans utiliser Clone()
    Par celes dans le forum C#
    Réponses: 3
    Dernier message: 26/03/2009, 11h31

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