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 :

Héritage et polymorphisme en C


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 7
    Par défaut Héritage et polymorphisme en C
    Bonjour,

    Dans son tutoriel sur l'héritage en C, http://chgi.developpez.com/c/heritage/ , CGi utilise la méthode suivante:
    Quand on veut qu'une structure hérite d'une autre structure, le début de la classe fille doit être le même que celui de la classe mère. Les nouveaux attributs sont ajoutés à la fin.

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    struct Mere {
       int a;
       int b;
    };
     
    struct Fille {
       // membres de Mere
       int a;
       int b;
       // membres de Fille
       int c;
    }
    Il utilise le polymorphisme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct Mere *m;
    struct Fille f = { 1, 2, 3 };
     
    m = (struct Mere *) &f;
    // utiliser m->a et m->b
    Le C garantit que le premier élément de la structure est à l'addresse 0, donc ça doit marcher pour "a" tout le temps.
    Ma question est: est-ce que pour les autres éléments de la structure, ça marchera quelque soit le type et le nombre d'attributs, et quelque soit le compilateur ? Parce que le compilateur peut également ajouter des octets de remplissage (padding).

  2. #2
    Membre actif
    Homme Profil pro
    autodidacte
    Inscrit en
    Mai 2015
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 16
    Par défaut
    Pourquoi ne pas passer au C++ ?

    Sinon, il y a les struct, les énum. Et ne pas utiliser de variables globales.

  3. #3
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Je te déconseille ce genre de code. Si les optimisations de compilation en vectorisation sont utilisées, ton code ne fonctionnera probablement plus.
    Exemple avec xlC, le compilateur IBM AIX :
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct
    {
            int a;
            int b;
    } premier;
     
    typedef struct
    {
            int a;
            int b;
            char c;
    } second;
     
    int main( void )
    {
            second s;
            s.a = 10;
            s.b = 40;
            s.c = 2;
            premier * p = (premier *)((void*)& s);
            printf( "a=%d, b=%d\n", p->a, p->b );
            exit( 0 );
    }
    Ce code fonctionne très bien en compilant avec xlC sans aucune option.
    Par contre, en compilant avec : xlc -O3 -qarch=pwr6 -qsimd=auto mon_prog.c, l'affichage devient faux par rapport à ce qu'on attend.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  4. #4
    Membre très actif

    Femme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    591
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 591
    Par défaut
    Quand on veut qu'une structure hérite d'une autre structure, le début de la classe fille doit être le même que celui de la classe mère
    Je ne trouve pas çà très malin... Si tu dois modifier ton objet mère, tu dois faire la même modif sur tous les objet qui en hérite...

    Je préfère comme ca:

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct
    {
            int a;
            int b;
    } premier;
     
    typedef struct
    {
            premier p;
            char c;
    } second;
     
    int main( void )
    {
            second s;
            s.p.a = 10;
            s.p.b = 40;
            s.c = 2;
            premier * p = &s.p;
            printf( "a=%d, b=%d\n", p->a, p->b );
            exit( 0 );
    }

  5. #5
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par dinobogan
    Si les optimisations de compilation en vectorisation sont utilisées, ton code ne fonctionnera probablement plus.
    Probablement car la règle de l’aliasing est violée.

    Citation Envoyé par dinobogan
    Par contre, en compilant avec : xlc -O3 -qarch=pwr6 -qsimd=auto mon_prog.c, l'affichage devient faux par rapport à ce qu'on attend.
    Par curiosité, ça affiche quoi ?


    Citation Envoyé par mith06
    Je ne trouve pas çà très malin... Si tu dois modifier ton objet mère, tu dois faire la même modif sur tous les objet qui en hérite...
    Yep, c’est vraiment un handicap pour quand le code évolue (en plus du problème d’aliasing).

    Citation Envoyé par mith06
    Je préfère comme ca:
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct
    {
            int a;
            int b;
    } premier;
     
    typedef struct
    {
            premier p;
            char c;
    } second;
     
    int main( void )
    {
            second s;
            s.p.a = 10;
            s.p.b = 40;
            s.c = 2;
            premier * p = &s.p;
            printf( "a=%d, b=%d\n", p->a, p->b );
            exit( 0 );
    }
    En plus d‘une meilleure maintenabilité, ça devrait résoudre le problème observé par dinobogan.

    @dinobogan : tu peux tester le code de mith06 avec xlC pour voir si tu as toujours un résultat faux ?

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2009
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2009
    Messages : 218
    Par défaut
    Bonjour,

    Personnellement je pense que cet article sur la POO en C n'est pas celui qu'il faut rédiger/lire, si le but est d'introduire les programmeurs à la POO.

    On ne peut pas introduire un paradigme en partant du paradigme en question, où la scission/transition dans ce cas?

    Le C n'est pas fait pour de l'objet, c'est un langage impératif et c'est comme cela que ça marche.

    En revanche, une meilleure façon de faire passer les programmeurs du C au C++ est une introduction et un apprentissage du C modulaire, qui est d'ailleurs largement adopté dans le développement logiciel en C, le code du noyeau linux par exemple.

    Le fond de l'article n'est pas mal, mais je le reprendrais bien en un cours sur le C modulaire, qui ferait rester le lecteur dans le C et le paradigme associé, en lui montrant une meilleure approche de la POO/C++.

    Je sais que mon post ne répond pas à la question posé, mais je ne n'ai pas vu où laisser un commentaire sur la page du cours en question.

    Bien cordialement

  7. #7
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Citation Envoyé par grim7reaper Voir le message
    Par curiosité, ça affiche quoi ?
    Ca affiche : a=804396748, b=804396756
    Ces deux valeurs ne changent pas, même après avoir changer les affectations '10' et '40'.
    @dinobogan : tu peux tester le code de mith06 avec xlC pour voir si tu as toujours un résultat faux ?
    Ce code fonctionnera sans problème. Mais je teste quand même...
    Après test, ça fonctionne sans problème. Et heureusement, sinon on ne pourrait plus utiliser les structures
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  8. #8
    Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 7
    Par défaut
    dinobogan,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    premier * p = (premier *)((void*)& s);
    A quoi sert le premier cast ici ? (void *)

    PS: La norme C garantit que l'adresse d'une structure est l'adresse de son premier élément, donc p->a devrait valoir 10.

Discussions similaires

  1. héritage et polymorphisme
    Par julien.metais dans le forum Hibernate
    Réponses: 3
    Dernier message: 17/05/2009, 09h58
  2. Réponses: 10
    Dernier message: 17/07/2008, 20h01
  3. héritage et polymorphisme
    Par davdou dans le forum JSF
    Réponses: 2
    Dernier message: 23/11/2007, 09h51
  4. [C#] Information sur héritage et polymorphisme
    Par LE NEINDRE dans le forum C#
    Réponses: 21
    Dernier message: 14/06/2007, 11h00
  5. Réponses: 19
    Dernier message: 05/06/2007, 08h13

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