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 :

[POO] Héritage et méthode non implémentée


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut [POO] Héritage et méthode non implémentée
    Bonjour,

    J'aimerai savoir pourquoi le code suivant fonctionne (aucun probleme a la compilation ni à l'éxecution) :

    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
    class CTest
    {
    };
     
    class CTest2 : public CTest
    {
    };
     
    class CTest3 : public CTest
    {
    public:
    void CTest3::Affiche()
    {
    	cout<<"Bonjour";
    };
    };
     
    void main()
    {
    	CTest2 test2;
    	CTest3* ptr3;
     
    	ptr3 = (CTest3*) &test2;
    	ptr3->Affiche();
    }
    L'objet test2 n'a pas de méthode affiche. Je ne comprend pas pourquoi a l'execution je n'est pas de problème (j'ai bien l'affichage 'Bonjour'). Si quelqu'un pouvait m'indiquer ou (est surtout quand) est mis en mémoire le code de la méthode n'affiche. Un pointeur m'est-il du code en mémoire (ou plutot lors du transtypage)? Merci d'avance =)

  2. #2
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptr3 = (CTest3*) &test2;
    Ici tu fais un cast "C", ce qui signifie qu'il n'y a aucune vérification sur la compatibilité entre les types, et donc qu'il te laisse faire une erreur.

    Utilises static_cast à la place et tu verras le probleme à la compilation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptr3 = static_cast<CTest3*>( &test2 ); // erreur à la compilation
    C'est une des raisons pour lesquelles il est conseiller d'utiliser les casts du C++ (static_cast, dynamic_cast, reinterpret_cast, const_cast) plutot que celui du C.

    Sinon, ton code, il me semble, est censé faire un "comportement indéfini". Dans certains contextes il aurait peut être crashé au runtime, ou pire manipulé la mémoire sans que ce soit visible.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Points : 379
    Points
    379
    Par défaut
    Le programme fonctionne parce que par chance il ne fait rien d'invalide. Tu peux essayer quelque chose dans le genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class CTest3 : public CTest
    {
    public:
    int toto;
    };
     
    void main()
    {
    	CTest2 test2;
    	CTest3* ptr3;
     
    	ptr3 = (CTest3*) &test2;
    	ptr3->toto = 5;
    }
    Ca va compiler mais certainement planter à l'exécution, parce qu'un objet CTest3 a le membre "toto" en plus (donc taille plus grande en mémoire) dont ne dispose pas un objet CTest2. Ce qui me ferait dire que si tu ne fais que rajouter des méthodes et pas des membres il n'y a pas de problème (à vérifier, "don't quote me on that" comme on dit).

    Edit: voir la réponse de Klaim ci-dessus qui m'a précédé

  4. #4
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut
    On m'a toujours dis que les attributs et méthodes d'une classe était mis en mémoire lors de l'instanciation. Ce que je ne comprend pas c'est que je n'instancie pas CTest3. Pourtant lorsque j'appelle la méthode Affiche() j'ai bien 'Bonjour' dans la console. Donc ma question est quand est mis en mémoire le code de la méthode affiche(). Je suppose que c'est lors du transtypage mais je n'en suis pas sur. Je comprend que le cast en C me laisse faire une erreur ce que je ne comprend pas c'est qu 'a l'execution il n'y est pas d'erreur.

    Edit : Je cast d'une classe fille a une autre classe fille et non d'une classe fille a une classe mere.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ca va certainement faire bondir les puristes, mais à l'exécution, tu peux considérer ta méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void CTest3::Affiche()
    {
    	cout<<"Bonjour";
    };
    comme une fonction globale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Affiche()
    {
    	cout<<"Bonjour";
    };
    vu que le paramètre this n'est utile en rien. C'est pour ça que ça ne plante pas.
    Après ce qui concerne la mémoire, là c'est uniquement du code. Il n'y a pas de données associées qui dépend du type. Donc, ce code se retrouve en mémoire indépendamment de l'allocation ou non d'un objet de type CTest3.

  6. #6
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Keweed Voir le message
    On m'a toujours dis que les attributs et méthodes d'une classe était mis en mémoire lors de l'instanciation. Ce que je ne comprend pas c'est que je n'instancie pas CTest3. Pourtant lorsque j'appelle la méthode Affiche() j'ai bien 'Bonjour' dans la console. Donc ma question est quand est mis en mémoire le code de la méthode affiche(). Je suppose que c'est lors du transtypage mais je n'en suis pas sur. Je comprend que le cast en C me laisse faire une erreur ce que je ne comprend pas c'est qu 'a l'execution il n'y est pas d'erreur.
    ptr3 est un pointeur, c'est le pointeur qui est instancié ici.
    En faisant ton cast, ce que tu demandes à la machine c'est de considérer que la stucture de test2 (qui est de type CTest2) est en fait de type CTest3, donc quand tu manipules ptr3 le compilateur va considérer qu'il y a au bout du pointeur est structuré dans la mémoire comme CTest3, ce qui n'est pas forcément le cas (comme ici).

    Le static_cast permet justement que le compilateur vérifie que tu ne fais pas ce genre de chose, parceque généralement, ça n'a aucun sens.

    Edit : Je cast d'une classe fille a une autre classe fille et non d'une classe fille a une classe mere.
    Et alors? C'est justement ce qui est le pire!
    Tu ne devrais jamais faire ça (sauf cas très exceptionnel qui a peu de chances d'arriver).

  7. #7
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut
    Klaim, je sais bien qu'il ne faut jamais faire ca d'ailleur je ne le fais jamais (a part la mais c'etais volontaire). Je voulais juste savoir ce qu'il se passait au niveau mémoire car je croyais que le code des méthodes était mis en mémoire lors de l'instanciation et je ne comprenais donc pas pourquoi il n'y avait pas de problème à l'execution. Si j'ai bien compris ce qu'a dis 3Darchi les méthodes d'une classe sont mise en mémoire même sans instancier un objet. Merci de ta réponse. Je comprend maintenant pourquoi il n'y a pas d'erreur à l'execution.

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Keweed Voir le message
    Klaim, je sais bien qu'il ne faut jamais faire ca d'ailleur je ne le fais jamais (a part la mais c'etais volontaire). Je voulais juste savoir ce qu'il se passait au niveau mémoire car je croyais que le code des méthodes était mis en mémoire lors de l'instanciation et je ne comprenais donc pas pourquoi il n'y avait pas de problème à l'execution. Si j'ai bien compris ce qu'a dis 3Darchi les méthodes d'une classe sont mise en mémoire même sans instancier un objet. Merci de ta réponse. Je comprend maintenant pourquoi il n'y a pas d'erreur à l'execution.
    Les méthodes ne sont pas chargées en mémoire, ce sont des fonctions comme toute autre fonction. En revanche, pour les données, c'est autre chose.

    En fait, ta classe, c'est juste une structure comme en C, avec des fonctions qui gravitent autour, mais sans lien direct avec la structure (sauf si tu fais des virtual). C'est juste une simplification de l'écriture, riend e plus

  9. #9
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut
    Merci pour vos réponses. J'y vois plus clair maintenant.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Les méthodes ne sont pas chargées en mémoire, ce sont des fonctions comme toute autre fonction.
    Enfin, si, elles sont chargées en mémoire mais pas dans la zone de données mais dans la zone de code. Et elles le sont comme toutes fonctions indépendamment des données. Ne serait-ce que pour ne pas avoir autant de fois le code en mémoire que d'instance d'objet...

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Enfin, si, elles sont chargées en mémoire mais pas dans la zone de données mais dans la zone de code. Et elles le sont comme toutes fonctions indépendamment des données. Ne serait-ce que pour ne pas avoir autant de fois le code en mémoire que d'instance d'objet...
    Merci d'avoir été plus précis que moi

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

Discussions similaires

  1. [POO] Héritage et fonction non implémentée
    Par delire8 dans le forum C++
    Réponses: 21
    Dernier message: 20/11/2008, 21h55
  2. [POO] [Héritage] Méthode non héritée
    Par WebDream dans le forum Langage
    Réponses: 9
    Dernier message: 09/10/2008, 13h52
  3. [POO] Héritage et surcharge de méthodes
    Par defkid dans le forum Langage
    Réponses: 4
    Dernier message: 26/02/2007, 14h51
  4. [POO] Héritage d'une méthode getInstance ?
    Par knocc dans le forum Langage
    Réponses: 4
    Dernier message: 13/02/2007, 19h47
  5. [Héritage] Redéfinition méthode
    Par petit-ourson dans le forum Langage
    Réponses: 9
    Dernier message: 06/05/2004, 16h06

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