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, héritage et méthodes virtuelles


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Par défaut Exceptions, héritage et méthodes virtuelles
    Bonjour,

    Cela fait plusieurs heures que je bloque sur le problème suivant. Voici mon bout de code de test de l'architecture des exceptions pour mon projet :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    // Classe de base des exceptions
    class Exception {
    public :
        Exception() : next(NULL) {}
        Exception& add(Exception& e) {
            Exception* tmp = this;
            while (tmp->next != NULL)
                tmp = tmp->next;
            tmp->next = &e; 
            return *this;
        }
        virtual string show() { return "Classe Exception"; }
        Exception* next;
    };
     
    // Première exception
    class ExceptionA : public Exception {
    public:
        virtual std::string show() { return "Classe ExceptionA"; }
    };
     
    // Seconde exception
    class ExceptionB : public Exception {
    public:
        virtual std::string show() { return "Classe ExceptionB"; }
    };
     
    // Affichage;
    ostream& operator<<(ostream& out, Exception& e) {
        out << e.show() << endl;
        if (e.next != NULL)
            out << *e.next;
        return out;
    }
     
    int main(int argc, char *argv[])
    {
        // Test d'une exception basique
        try {
            throw ExceptionA();
        } catch (Exception& e) {
            // On attend l'affichage :
            // Class ExceptionA
            cout << "Test simple :" << endl << e << endl;
        }
     
        // Test d'une exception en cascade n°1
        try {
            try {
                throw ExceptionA();
            } catch (Exception& e) {
                ExceptionB b = ExceptionB();
                b.add(e);
                throw b;
            }
        } catch (Exception& e) {
            // On attend l'affichage :
            // Class ExceptionB
            // Class ExceptionA
            cout << "Test cascade n°1 :" << endl << e << endl;
        }
     
        // Test d'une exception en cascade n°2
        try {
            try {
                throw ExceptionA();
            } catch (Exception& e) {
                throw ExceptionB().add(e);
            }
        } catch (Exception& e) {
            // On attend l'affichage :
            // Class ExceptionB
            // Class ExceptionA
            cout << "Test cascade n°2 :" << endl << e << endl;
        }
     
        return 0;
    }
    Comme vous l'aurez probablement affiché il "foire" au test en cascade n°2 et m'affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Test cascade n°2 :
    Classe Exception
    Classe ExceptionA
    Vous avez une idée de la raison pour laquelle cela ne fait pas du tout ce que j'attends ? De plus la classe Exception ne sera jamais instanciée, je voulais en faire une classe abstraitre mais cela ne fonctionne pas avec l'envoi d'exceptions :/ c'est la raison pour laquelle j'ai défini la méthode Exception::show()

    Merci beaucoup de votre aide.

    Nuwanda

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Nuwanda
    Vous avez une idée de la raison pour laquelle cela ne fait pas du tout ce que j'attends?
    L'objet jete est copie avant d'etre passe au catch. Et la copie se fait avec le type statique de l'objet jete. Le type statique de
    c'est le type du resultat de add(), donc Exception.
    De plus la classe Exception ne sera jamais instanciée, je voulais en faire une classe abstraitre mais cela ne fonctionne pas avec l'envoi d'exceptions :/
    Meme cause. La copie generee ci-dessus est une instantiation.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Par défaut
    Merci beaucoup. J'ai mis un moment à comprendre, mais avec quelques affichage d'addresses mémoire et 2-3 tests j'ai compris pourquoi cela foire. C'est donc le throw qui copie l'objet.

    Si l'objet est copié quelle est l'utilité d'avoir le "&" dans le catch ? Vu que l'on ne manipule pas l'objet lancé ?!?!? Donc si on ne met pas le "&" on copie deux fois l'objet ?

    Y'a-t-il un moyen de contourner ce problème ? Peut-être en rusant avec le constructeur par copie (mais c'est juste une hypothèse, je ne maitrise pas vraiment ce domaine) ?

  4. #4
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    en effet, à priori, si on ne mets pas le & dans le catch, il y a deux copies...

    pour ce qui est de ruser... le seul moyen que je vois semble être de lever en fait un pointeur, alloué avec new, mais c'est pas terrible : il faut le delete, et en plus, c'est même pas sûr qu'un Exception* catch un ExceptionB*
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Swoög
    c'est même pas sûr qu'un Exception* catch un ExceptionB*
    Si.

  6. #6
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Si.
    OK, merci beaucoup
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Par défaut
    Donc, je viens de faire 2-3 tests...

    Si j'ajoute la constructeur par copie dans la classe Exception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Exception(const Exception& e) { cout << "Copie de l'objet " << &e << " dans " << this << endl; }
    J'obtiens 2 choses intéressantes :
    - Quand on ne met pas le "&" dans le catch, on a bien deux copies. (mais c'est pas le plus bizarre)
    - Il ne m'affiche que la première exception et pas celle ajoutée à la suite ?!?!?

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Nuwanda
    J'obtiens 2 choses intéressantes :
    - Quand on ne met pas le "&" dans le catch, on a bien deux copies. (mais c'est pas le plus bizarre)
    C'est pas bizarre, c'est attendu.

    - Il ne m'affiche que la première exception et pas celle ajoutée à la suite ?!?!?
    Et le champs next, il est initialise comment? J'ai comme l'impression que par chance il contient un pointeur nul.

    Au fait, il manque le clean up de ce qui est alloue dynamiquement.

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Nuwanda
    Si l'objet est copié quelle est l'utilité d'avoir le "&" dans le catch ?
    Ne pas copier une deuxieme fois, ce qui dans le cas present tronquerait tous les objets lances a leur type de base, Exception.

    Y'a-t-il un moyen de contourner ce problème ? Peut-être en rusant avec le constructeur par copie (mais c'est juste une hypothèse, je ne maitrise pas vraiment ce domaine) ?
    Tu veux un comportement polymorphe en meme temps qu'une semantique de copie. Donc il faut jeter un pointeur, eventuellement encapsule pour s'assurer de sa destruction a bon escient.

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

Discussions similaires

  1. méthode virtuelle dans héritages
    Par bobby51 dans le forum Langage
    Réponses: 4
    Dernier message: 21/02/2010, 19h36
  2. héritage et méthode virtuelle
    Par cibatro dans le forum Langage
    Réponses: 11
    Dernier message: 28/07/2009, 17h13
  3. méthode virtuelle pure et héritage
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 20/07/2009, 22h12
  4. héritage et méthodes virtuelles ?
    Par Didine981 dans le forum C++
    Réponses: 4
    Dernier message: 08/12/2007, 13h43
  5. [Héritage] Downcasting et méthodes virtuelles
    Par poukill dans le forum C++
    Réponses: 8
    Dernier message: 16/07/2007, 13h38

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