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 :

Detruire une instance dans son constructeur


Sujet :

C++

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut Detruire une instance dans son constructeur
    Bonjour,

    J'ai une classe dans laquelle j'aimerais faire des initialisations diverses (ouverture de fichier, tests, etc). Dans le cas ou ces tests ne sont pas satisfaits, comment puis-je faire pour detruire l'objet dans son constructeur et/ou generer une exception retrouvable par try ... catch .

    Enfin, si vous avez une solution plus simple... Sinon je pensais a un simple flag dans la classe qui serait a FALSE et que je devrais tester lors de la construction, et de faire un delete de l'objet au cas ou les tests ne sont pas concluants.

    Mais je preferais utiliser une methode plus "clean" que cette histoire de flag.

    Merci d'avance...

    -g13

  2. #2
    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
    throw uneExceptionQuiIndiqueLaCauseDeLErreur
    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.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Et rapide avec ca

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Avant de mettre ce topic "resolu", j'ai une derniere question: comment construire l'instance de ma classe sans passer par un "new" et gerer ces exceptions?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    MaClasse Instance(..,..);
     
    // ... et ensuite, comment gerer les exceptions??
    au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    MaClasse *Instance;
     
    try
    {
       Instance = new MaClasse(..,..);
    }
    catch (int)
    {
       // Exception...
    }

  5. #5
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Tu peux gerer ça avec une methode statique + un constructeur "protected" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class MaClass
    {
    protected:
      MaClass();
     
    public:
      static MaClass* construire();
    }
    Et :

    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
    MaClass* MaClass::construire()
    {
      MaClass* retour;
     
      try
      {
         retour = new MaClasse();
      }
      catch(...)
      {
         retour = NULL;
      }
     
      return retour;
    }
    Ainsi, il est impossible d'appeler le constructeur directement. Le seul moyen de construire une instance de MaClasse est d'appeller la méthode "construire" qui renvoit NULL si l'instance n'a pas pu être construite.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Merci pour la reponse, mais je me suis apparemment mal exprime: je demandais s'il etait possible de ne pas passer par un pointeur pour declarer mon instance...

    Je reexplique: je voudrais pouvoir declarer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClasse Instance(..,..);
    et non

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClasse *Instance = ...;
    C'est juste pour une question de compatibilite avec mes precedentes version de la classe. Si les utilisateurs de cette classe doivent changer de la declaration sans pointeur a celle "avec", alors ils sont obliges de modifier la syntaxe:

    a

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Instance->Methode1(...)
    Ce n'est pas tres tres grave (passqu'on n'est pas tres avance dans le projet), mais je voudrais savoir comment faire tant qu'a faire...

  7. #7
    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
    Tu peux toujours déclarer : MaClasse Instance(..,..);

    Eventuellement avec un try/catch tout autour (ou le plus souvent, à un niveau plus haut dans la pile d'appels) pour gérer le cas à erreur.
    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.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Le probleme c'est que si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    try
    {
    	LogManager Test("C:\\MyLog.log",TRUE);
    	printf("Success!\n");
    }
    catch (int)
    {
    	printf("Failure!\n");
    	return;
    }
     
    Test.ToggleLogFileOutput(TRUE);
    il me jette en disant que Test n'est pas defini... Ca voudrait dire que Test ne peut pas exister en dehors du bloc "try"

  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
    Oui, mais qu'est-ce qui t'empêche d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try
    {
    	LogManager Test("C:\\MyLog.log",true);
    	printf("Success!\n");
    	Test.ToggleLogFileOutput(true);
    }
    catch (int)
    {
    	printf("Failure!\n");
    	return;
    }
    PS : true s'écrit true en C++, pas TRUE, qui n'est qu'un #define inutile sur certaines plateformes.
    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 régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Re,

    Ben comme j'ai dit precedemment, c'est seulement pour eviter a mes codeurs d'avoir a trop compliquer les changements dans leurs codes (deja ecrits pour certains), mais si y'a pas d'autres moyens, on fera comme ca.

    Sinon pour le TRUE, c'est effectivement une redefinition.

  11. #11
    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
    Si le cas d'erreur est vraiment exceptionnel, et selon le type de gestion d'erreur demandé, rien ne t'empêche d'ajouter un simple try/catch dans le main pour sortir du programme proprement en indiquant le problème, sans rien changer au reste du code.
    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.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Bon OK... je crois qu'on va rester sur l'utilisation de pointeurs

    Merci beaucoup!*

    -Gorgo T.

    *trop fort ce forum!

  13. #13
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Sinon, tu peux aussi ecrire un "wrapper" de pointeur :
    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
     
    class Wrapper
    {
      private:
        MaClasse* p_pointeur;
     
      public:
         Wrapper();
         void setPointeur(MaClasse* pointeur);
     
      public:
         void MaMethode_1();
         void MaMethode_2();
          ....
    }
    Et :

    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
    Wrapper::Wrapper()
    {
      p_pointeur = NULL;
    }
     
    Wrapper::setPointeur(MaClasse* pointeur)
    {
      p_pointeur = pointeur
    }
     
    Wrapper::MaMethode_1()
    {
      if (p_pointeur)
      {
        return p_pointeur->MaMethode_1();
      }
     
       return CodeErreur;
    }

    Comme ça, après tu utilises :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    LogWrapper wrapper;
     
    try
    {
    	LogWrapper.setPointeur(new LogManager("C:\\MyLog.log",TRUE);
    	printf("Success!\n");
    }
    catch (int)
    {
    	printf("Failure!\n");
    	return;
    }
     
    wrapper.ToggleLogFileOutput(TRUE);
    Mais bon, ça commence à devenir compliqué pour pas grand-chose....

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Points : 78
    Points
    78
    Par défaut
    Ok, merci pour le tuyau, je connaissais pas cette maniere de faire. On va aviser...

    -GT

  15. #15
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Sujet intéressant.
    Il me rappelle deux conseils qu'on m'avait donné en son temps:
    -en faire le moins possible dans les constructeurs (en prévoyant des méthodes d'initialisation);
    -ne pas abuser des exceptions (voire les éviter).

    En prenant exemple sur ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    LogManager Test;
    if (Test.Init("C:\\MyLog.log",true))
    {
    	printf("Success!\n");
    	Test.ToggleLogFileOutput(true);
    }
    else
    	printf("Failure!\n");

  16. #16
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    Il me rappelle deux conseils qu'on m'avait donné en son temps:
    -en faire le moins possible dans les constructeurs (en prévoyant des méthodes d'initialisation);
    -ne pas abuser des exceptions (voire les éviter).
    Deux très mauvais conseils.
    Il y a une raison pourquoi une variable déclarée dans un try n'est visible que dans celui-ci. C'est pour garantir l'invariant que si la variable ne peut être construite, il n'est pas possible d'y accéder et ainsi de manipuler un objet qui est dans un état non défini.
    Les constructeurs permettent de mettre en place des invariants, ce qui est beaucoup plus sûr.

    En dehors du fait que les pointeurs, c'est le mal, ça permet plein d'opérations dangereuses, c'est une gestion des ressources manuelle et donc l'exception-safety n'est pas garantie, ça peut aussi avoir un certain nombre d'états invalides ou un état "vide".
    Il est bien mieux de forcer à ce que tout objet soit initialisé avec des choses qui ont du sens à sa création, afin qu'il soit toujours dans un état utilisable.
    Boost ftw

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 24/11/2006, 12h21
  2. detruire une chaine dans un fichier texte
    Par rober dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 08/11/2006, 09h27
  3. Réponses: 1
    Dernier message: 18/05/2006, 16h00
  4. [ SWING ] Ouvrir une fenêtre dans son parent
    Par Invité dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 12/01/2006, 16h12
  5. Changer de base à l'intérieure d une instance dans un script
    Par Labienus dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 02/12/2005, 16h03

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