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 :

Exceptions dans le constructeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut [Résolu]Exceptions dans le constructeur
    Bonjour tout le monde!!

    N'ayant pas le temps d'apprendre le C++ correctement, je met les mains directs dans le cambouis, en m'aidant de votre formidable FAQ. Malheureusement j'ai quelque question qui me taraudes et qui sont tellement betes qu'elles n'apparaissent meme pas dans la faq.

    Enfin bref les voici :

    1-J'utilise des exceptions dans mon constructeur, comment je fais pour l'attraper depuis le main? Sachant que si je met la déclaration de la var dans le try elle ne devient plus visible en dehors. Je met tout le main dans le try? c'est pas un peu bizarre?

    2-J'utilise une classe "A" qui contient des objets d'une autre classe "B". Seulement lors ce que je déclare ces objets, je ne connais pas encore les valeurs que je dois passer au constructeur des objets de "B". Ces parametre je les récupere du constructeur de "A". Comment je fais pour appeler les constructeur des objet de "B" depuis celui de "A"?

    3-plus généralement peut-on appeler le constructeur pour réinitialiser un objet? genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MaClass MaVar();
    ... //on effectue quelques op sur MaVar
    MaVar.MaClass();//réinitialiser MaVar

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 159
    Par défaut
    instancier dynamiquement peut faire l'affaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    MaClass * MaVar =NULL;
    try
    {
     MaVar = new MaClass ;
    }
    catch( ...)
    {
    if(NULL !=MaVar )
    MaVar->MaClass();
    }
     
    //.....

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    1. En théorie, je dirais que tout le code qui utilise ton objet doit être entouré du bloc try. Reste à savoir s'il est normal que le code en question constitue la totalité du main().
    2. Il faut utiliser une liste d'initialisation (exemple à venir)
    3. Non. Mais si ta classe supporte un opérateur d'affectation, tu peux toujours faire maVar = MaClass(); à nouveau: Le constructeur par défaut et l'opérateur d'affectation seront successivement appelés.
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Exemple de liste d'initialisation:
    Code C++ : 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
    class B
    {
    public:
    	explicit B(int tata)
    	 : m_tata(tata)
    	{
    	}
    private:
    	int m_tata;
    };
     
    class A
    {
    public:
    	explicit A(int toto, int tata)
    	 : m_toto(toto), m_beta(tata)
    	{
    	}
    private:
    	int m_toto;
    	B m_beta;
    };
     
    int main(void)
    {
    	A alpha(10, 42);
    	return 0;
    }
    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.

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    (Hum ... Médinoc a trouvé une nouvelle façon pour qu'il n'y ait pas de réponse pendant qu'il saisit la sienne )

    3- Pourquoi la réinitialiser ? Crées-en une autre sur la pile si tu sors de la portée où sa précédente valeur avait du sens. Fais des fonctions, découpe, tout ça.
    (Il est difficile de faire une réponse générale, j'ai assez peu de besoin en objets "réinitialisables")

    Au fait
    déclare une fonction et non pas une variable -> virer les parenthèses.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    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 Luc Hermitte Voir le message
    (Hum ... Médinoc a trouvé une nouvelle façon pour qu'il n'y ait pas de réponse pendant qu'il saisit la sienne )

    3- Pourquoi la réinitialiser ? Crées-en une autre sur la pile si tu sors de la portée où sa précédente valeur avait du sens. Fais des fonctions, découpe, tout ça.
    (Il est difficile de faire une réponse générale, j'ai assez peu de besoin en objets "réinitialisables")

    Au fait
    déclare une fonction et non pas une variable -> virer les parenthèses.
    Ben, des exemples d'objets réinitialisables, ça intervient souvent en programmation 3D avec DirectX, quand on utilise des ressources non "managées" et qu'on a des pertes de "device"...

    Il faut alors regénérer ou recharger les ressources (géométrie, etc.) et les renvoyer à la carte graphique.

    J'avoue que moi j'utilisais alors souvent une construction en 2 temps, pour ne pas avoir à utiliser de pointeurs. Maintenant, je sais pas si je ferais comme ça toujours.

  7. #7
    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
    La réponse c'est de bien savoir quand utiliser des exceptions et où les ratrapper.

    Déjà oui il te faut un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    try
    { //...
    } 
    catch( const exception & e ) 
    { //..
    } 
    catch( ... )
    {// ...
    }
    Dans le main, ainsi que dans chaque fonction d'entrée d'un thread.

    C'est le comportement de base:

    si une exception est lancée, elle va remonter jusqu'au main et le programme va se terminer ( en indiquant la nature de l'exception avec e.what() ).

    Maintenant, à toi de savoir quelles exceptions sont à intercepter à quel endroit parce qu'elles ne doivent pas amener à la fermeture du programme.

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Citation Envoyé par disturbedID Voir le message
    1-J'utilise des exceptions dans mon constructeur, comment je fais pour l'attraper depuis le main?
    En lisant cette question, j'ai pensé à un chapitre du Thinking C++. Certes, je ne réponds pas à ta question, d'autres s'en sont de toutes façons déjà chargés, mais je peux t'encourager à lire ceci, si tu as du temps, http://bruce-eckel.developpez.com/li...=page_2#L1.1.5
    Tu pourras y trouver des éléments qui t'intéresseront voire dans la suite du document à y trouver des solutions à tes problèmes.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    merci pour les reponses, c'est innatendue.
    Donc :
    1-C'est ce que j'utilisais avant luther13 avec à la fin un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass MaVraieVar = *MaVar;
    C'est lourd je vais passer vers un try+catch² dans le main. merci pour les propositions.

    2- Médinoc.

    3-pas grave c'était juste un "sucre syntaxique". Je vais crée une fonction membre pour ça.
    ********************************
    Une derniere :

    4-Dans mon constructeur je fais un appelle explicite
    du destructeur juste avant le throw pour libérer les tableau allouer avec des "pointeurs cons". Est ce que le fait d'appeler le destructeur (pour détruire cet objet donc) à l'intérieur d'une mèthode de la class puis de continuer l'execution de la mèthode de cette objet ne cause t'il pas probleme (on ne rie pas s'il vous plais)?


    En tout cas, moi qui croyais que le C++ c'était du C avec des fonctions dans les struct je me prends une belle claque dans la gueule

  10. #10
    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 disturbedID Voir le message
    Est ce que le fait d'appeler le destructeur (pour détruire cet objet donc) à l'intérieur d'une mèthode de la class puis de continuer l'execution de la mèthode de cette objet ne cause t'il pas probleme (on ne rie pas s'il vous plais)?
    A la base, un delete this (ou un appel explicite au destructeur, mais c'est bien plus rare); est autorisé pour peu bien entendu qu'on ne fasse plus d'accès à une variable membre non statique de l'objet par la suite.

    Par contre, là, l'objet n'a pas encore été construit, puisque le constructeur n'a pas fini de s'exécuter. Même si je n'ai pas retrouvé dans la norme de texte à ce sujet, ça me semble très louche, et il me semble que ce n'est pas autorisé.

    Enfin qui te dis qu'au moment où tu attrapes l'exception, tu peux effacer les éléments de ton tableau ? Ce sont peut-être encore des pointeurs invalides...
    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.

  11. #11
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Si une exception sort du constructeur, tous les membres construits jusqu'au point de l'exception sont détruits (détruire un pointeur, comme tout autre scalaire (?), étant une no-op), et le destructeur jamais appelé (normal, l'objet n'a jamais été construit).

    Pour moi, si tu rajoutes un appel au destructeur (dans le constructeur) => comportement non déterminé/défini => tout peut arriver, en particulier, rarement du bon.
    Cf FAQ C++, chapitre sur le RAII, lien sur The big rule of Two qui est très bien sur ce sujet.

    (Et non, le C++ est bien différent (c'est relatif, hein?!) du C. On le voit bien sur tous ces aspects)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  12. #12
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    On m'a dit (mais je ne trouve rien sur le net pour appuyer) qu'un catch avec ellipsis dans un programme sous windows empechait celui ci d'etre certifié microsoft.

    Quelqu'un a plus d'infos ?

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/05/2008, 20h08
  2. Exception dans le constructeur
    Par olive_le_malin dans le forum C++
    Réponses: 9
    Dernier message: 24/05/2007, 18h02
  3. Réponses: 18
    Dernier message: 28/02/2007, 10h23
  4. exception dans un constructeur
    Par xxiemeciel dans le forum C++
    Réponses: 25
    Dernier message: 23/11/2005, 18h14
  5. Capture d'exception dans un constructeur
    Par declencher dans le forum Composants VCL
    Réponses: 8
    Dernier message: 03/02/2004, 12h52

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