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 :

exception dans un constructeur


Sujet :

C++

  1. #1
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut exception dans un constructeur
    Salut,

    Je programme en C++ et je suis actuellement confronté a la possibilité de lancer une exception dans un constructeur.

    j'ai trouvé le liens suivant sur developpez.com :
    http://www.developpez.com/c/megacours/x3910.html

    seulement il y a quelque chose qui m'echappe, que retourne le new quand une exception est lancée ? un objet partiellement intialisé ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // supposons que l'Exception a ete lancee est 
    // traitee en interne comme expliquée sur le lien
    Objet* obj = new Objet();
    que vaut obj ? est-il NULL ?

    XXiemeciel
    XXiemeciel

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut Re: exception dans un constructeur
    obj n'est pas cree. Il n'est meme pas accessible aux endroits ou tu peux
    capturer l'exception.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #3
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut Re: exception dans un constructeur
    Citation Envoyé par jmarc68
    obj n'est pas cree. Il n'est meme pas accessible aux endroits ou tu peux
    capturer l'exception.
    donc obj est NULL ?

    XXiemeciel
    XXiemeciel

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Non, obj n'est pas cree. Si tu lances une exception dans ton constructeur,
    new ne retourne rien, la propagation de l'exception continue et la ligne
    suivant ta definition n'est pas executee.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Citation Envoyé par jmarc68
    Non, obj n'est pas cree. Si tu lances une exception dans ton constructeur,
    new ne retourne rien, la propagation de l'exception continue et la ligne
    suivant ta definition n'est pas executee.
    donc il faudrait encapsuler dans un try/catch l'appel a new ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Objet * obj = NULL;
     
    try
    {
     obj = new Objet();
    }
    catch(...)
    {
    }
    j'espere que non car je ne peux pas reprendre les 8000 fichiers cpp de l'application pour rajouter un try/catch a chaque new.

    XXiemeciel
    XXiemeciel

  6. #6
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    And still we will be here, standing like statues ...

  7. #7
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Je vais legerement detourner la question initiale

    Est ce que en cas d'erreur de mon constructeur je peut faire quelquechose pour que new retourne NULL ?

    le fait que l'exception se propage en dehors du constructeur me gene trop pour que je puisse l'utiliser.

    XXiemeciel
    XXiemeciel

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Si tu quites ton constructeur par une exception, tu dois la recuperer quelque part, non? Si
    ca ne te plais pas, plutot que de quiter le constructeur par une exception, tu peux avoir
    un drapeau d'etat qui indique que ton objet n'est pas correctement initialise et le tester
    (un peu comme ce qui se passe pour les stream).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par xxiemeciel
    Est ce que en cas d'erreur de mon constructeur je peut faire quelquechose pour que new retourne NULL ?
    l
    Non. Pense au cas

    Class obj(args...);

    Il n'y a pas d'equivalent a NULL.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Merci de vos reponses,

    Je pense que puisque je ne peux pas repasser a travers tout le code pour voir a quelles endroits mon objet est utilisé et changer chaque appel a new, je vais tout simplement prevoir un comportement de l'objet speciifique aux mauvaises utilisations.

    XXiemeciel
    XXiemeciel

  11. #11
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il existe une version de new qui ne lève pas d'exception : new(std::nothrow). Par contre je ne sais pas si elle renvoie NULL seulement à la place de std::bad_alloc, ou si elle attrape toute exception et la transforme en NULL.

  12. #12
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Est ce que je pourrais redefinir new seulement pour mon objet ?

    XXiemeciel
    XXiemeciel

  13. #13
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Loulou24
    Il existe une version de new qui ne lève pas d'exception : new(std::nothrow). Par contre je ne sais pas si elle renvoie NULL seulement à la place de std::bad_alloc, ou si elle attrape toute exception et la transforme en NULL.
    C'est simplement une version de new qui le lance pas de std::bad_alloc.

    Quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Foo* p = new Foo();
    Bar* q = new(std::nothrow) Bar();
    est compile comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Foo* p = operator new(sizeof(Foo));
    new(p) Foo();
    Bar* p = operator new(std::nothrow, sizeof(Bar));
    new(q) Bar();
    L'exception lancee eventuellement par le constructeur a lieu alors que operator new a
    deja retourne.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  14. #14
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par xxiemeciel
    Est ce que je pourrais redefinir new seulement pour mon objet ?
    Non. Les possibilites de surcharge de new ne permettent pas ce genre de chose. Seulement
    de changer ce qui concerne l'allocation memoire.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  15. #15
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Bon dans ce cas je vais rester sur ma premiere idée et faire un comportement special de l'objet plutot que de lancer une exception.

    Merci
    XXiemeciel
    XXiemeciel

  16. #16
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Tu ne peux pas envelopper ta construction ?
    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...

  17. #17
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Citation Envoyé par jmarc68
    Citation Envoyé par xxiemeciel
    Est ce que je pourrais redefinir new seulement pour mon objet ?
    Non. Les possibilites de surcharge de new ne permettent pas ce genre de chose. Seulement
    de changer ce qui concerne l'allocation memoire.
    Je n'ai jamais testé de redéfinir new, mais le tout premier lien donné (http://www.developpez.com/c/megacours/x3910.html) donne ce bout de code:
    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
    class A
    {
    public:
        A() throw (int);
        ~A();
     
        static void *operator new(size_t taille)
        {
            cout << "new()" << endl;
            return malloc(taille);
        }
     
        static void operator delete(void *p)
        {
            cout << "delete" << endl;
            free(p);
        }
    };
    Est-ce que ca redéfinit l'operateur new peu importe son contexte d'utilisation ? Et si oui, quel est l'intérêt de le mettre comme operateur statique de la classe A ?
    And still we will be here, standing like statues ...

  18. #18
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par bigquick
    Je n'ai jamais testé de redéfinir new, mais le tout premier lien donné (http://www.developpez.com/c/megacours/x3910.html) donne ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    definition de new et de delete en tant que membres statiques
    Est-ce que ca redéfinit l'operateur new peu importe son contexte d'utilisation ? Et si oui, quel est l'intérêt de le mettre comme operateur statique de la classe A ?
    Definir un operateur new comme membre (il est alors d'office statique, que l'on l'indique comme tel ou non) fait qu'il est utilise pour allouer des instances de lla classe et ses descendants (mais pas pour allouer autre chose dans les membres de la classe et des descendants).

    C'est donc une technique beaucoup moins brutale que de substituer l'operateur new global (qui alors s'impose a toutes les classes ne definissant pas d'operateur new membre). La definition d'un operateur new global devrait etre reserve a l'application et jamais impose par des bibliotheques.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  19. #19
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Ici ce n'est pas new le problème, mais le constructeur de l'objet.
    l'exception peut être est levée même sans new:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try
    {
        Object obj; // peut lever une exception
    }
    catch ( ... )
    {
        // et là je fais quoi ?
    }
    Si tu peux revoir la conception de la classe c'est peut être mieux que de bricoler new, ou alors créer un objet d'encapsulation ou une fonction de création comme le suggère Luc.

  20. #20
    Membre averti Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Points : 352
    Points
    352
    Par défaut
    Allo,

    Merci pour vos reponses, mais je fais du refactoring de code et cette objet est tres utilisé dans le code je ne peux pas me permettre de le changer completement ou de modifier les appels deja existant a cette objet, il y en a beaucoup trop.

    Ca aurait été bien plus pratique pour moi que new retourne NULL dans le cas d'un echec du constructeur car tout les ancien appel au constructeur aurait continuer a fonctionner puique les pointeur sont testé systematiquement.

    XXiemeciel
    XXiemeciel

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/05/2008, 20h08
  2. Exceptions dans le constructeur
    Par disturbedID dans le forum C++
    Réponses: 20
    Dernier message: 14/02/2008, 13h42
  3. Exception dans le constructeur
    Par olive_le_malin dans le forum C++
    Réponses: 9
    Dernier message: 24/05/2007, 18h02
  4. Réponses: 18
    Dernier message: 28/02/2007, 10h23
  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