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++

  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 : 38
    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 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.

  6. #6
    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.

  7. #7
    Expert confirm�
    Avatar de Swo�g
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    D�tails du profil
    Informations personnelles :
    �ge : 38
    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)

  8. #8
    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 ?!?!?

  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
    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.

  10. #10
    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 de votre aide � tous, j'ai r�solu mon probl�me en utilisant des pointeurs, ca fonctionne maintenant exactement comme je le souhaite.

    Voici le code correspondant :
    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 string show() { return "Classe ExceptionA"; }
    };
     
    // Seconde exception
    class ExceptionB : public Exception {
    public:
        virtual 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 new 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 new ExceptionA();
            } catch (Exception* e) {
                ExceptionB* b = new 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 new ExceptionA();
            } catch (Exception* e) {
                throw (new ExceptionB())->add(e);
            }
        } catch (Exception* e) {
            // On attend l'affichage :
            // Class ExceptionB
            // Class ExceptionA
            cout << "Test cascade n°2 :" << endl << e << endl;
        }
     
        return 0;
    }
    Question subsidiaire : Pourquoi il se m�lange les pinceaux entre type r�el et type d�clar� quand j'utilise les objet, mais quand j'utilise les pointeurs sur objet, il s'en sort parfaitement ?

  11. #11
    Expert confirm�
    Avatar de Swo�g
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par d�faut
    parce qu'il fait une copie de pointeur, c'est � dire qu'il copie "la valeur de l'adresse"

    alors que sinon, il copie la valeur de l'objet avec le type courant (dans ce cas Expression puisque ta fonction renvoie un Expression&
    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)

  12. #12
    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 !

  13. #13
    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
    Merci beaucoup de votre aide � tous, j'ai r�solu mon probl�me en utilisant des pointeurs, ca fonctionne maintenant exactement comme je le souhaite.

    Voici le code correspondant :
    Il a encore des problemes:
    1. il se fie au constructeur de copie, a l'operateur d'assignement et au destructeur par defaut pour une classe (Exception) ayant un membre pointeur; ce n'est generalement pas une bonne idee car on ne sait pas qui doit liberer ce pointeur. Dans les rares cas ou c'est adapte, je conseille de mettre un commentaire indiquant que c'est voulu.
    2. il y a des allocations de memoire sans liberation (probleme en partie lie au premier mais plus generalement, il n'a pas l'air d'avoir eu de reflexion sur ce probleme).

  14. #14
    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
    Bonjour,

    Tout d'abord, je vous remercie de votre inter�t pour mon projet ainsi que des �ventuels probl�mes que je vais renconter.

    Il faut savoir que les exceptions qui sont lanc�es doivent arr�ter le logiciel. En effet, je fais un traitement sur des donn�es, si le fichier de donn�es contient des erreurs, je ne peux continuer.

    Je dois avouer que pour le moment, ma pr�ocuppation n'est pas de savoir qui doit lib�rer la m�moire vu que le projet DOIT s'arr�ter en cas d'erreur. Je laisse le soin � l'OS de faire la lib�ration de m�moire (il s'agit bien �videmment d'une solution temporaire). Pour le moment, �tant donn� que le traitement sera tr�s long (plusieurs jours), je me pr�ocuppe principalement de v�rifier que l'espace m�moire ne gonfle pas lors du traitement.

    Pour la lib�ration de la m�moire des exceptions lorsque celles ci sont reli�es, chaque exception supprime la suivante. Th�oriquement le code suivant fonctionne comme je le souhaite (enfin j'esp�re...)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    Exception::~Exception()
    {
        delete next;
    }
    S'il n'y a pas de suivant, next est � NULL, donc cela s'arr�te. De plus le destructeur est virtuel.

    Sinon lorsque je vais d�velopper la lib�ration de m�moire, mes donn�es ont une structure arborescente qui fait que chaque �lement se chargera de supprimer les suivants et ainsi de suite. J'esp�re un joli fonctionnement en cascade. Ma seule crainte en r�alit� vient de la librairie que j'utilise et j'esp�re qu'elle n'a pas trop de fuites m�moires...

    Bonne journ�e !

+ 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. 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