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 :

Fonctions POO en C


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut Fonctions POO en C
    Bonjour a vous tous, je voulais savoir si on pouvait faire autrement que envoyer la structure a la fonction, Je m'explique, ma structure contient une fonction qui s'apelle afficher(en pointeur bien sûr) et une variable, mais pour afficher, je suis obliger d'envoyer ma structure, je voudrais qu'on est pas besoin de le faire, en passant par une variable globale par exemple?

    Est ce possible, j'aimerais une réponse merci

    Cordialement

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Un exemple nous aiderait à comprendre mieux je pense.

    Sinon, on peut tout à fait faire de la POO en C sans exposer les structures utilisées (on parle de pointeur opaque). Le meilleur exemple de ceci est la manipulation de fichier (FILE, fopen, fclose...)

    Exemple (attention, il manque les tests de retour des fonctions et la vérification des paramètres):
    Déclaration
    Code objet.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct mon_objet_secret *MON_OBJET;
     
    /* méthode */
    void action(MON_OBJET *objet);
    /* constructeur */
    MON_OBJET * creer(void);
    /* destructeur */
    detruire(MON_OBJET *objet);
    Définition :
    Code objet.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
    struct mon_objet_secret { 
        int champ;
    };
    /* methode */
    void action(MON_OBJET *objet)
    {
        printf("champ vaut %d\n", champ);
    }
    /* constructeur */
    MON_OBJET creer(void)
    {
        mon_objet_secret *obj = malloc(sizeof *obj);
        obj->champ = 10;
        return obj;   
    }
    /* destructeur */
    detruire(MON_OBJET *objet)
    {
        free(objet);
    }

    Utilisation :
    Code main.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "objet.h"
    int main(void) {
        MON_OBJECT *obj = creer();
     
        action(obj);
     
        detruire(obj);
     
        return 0;
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 214
    Points : 310
    Points
    310
    Par défaut
    Dans ce cas, cela revient au même au niveau de ta fonction. Que ta variable soit dans la pile ou le tas, elle reste présente.

    Mais en terme de programmation, il vaut mieux éviter les variables globales, c'est une règle que tu as déjà dû rencontrer.

    Certes cela te permet une flexibilité imbattable. Mais tu arrives vite à quelque chose d'ingérable : objet pouvant être appelé dans n'importe quel contexte, et donc toute modification fait que tu dois tester tout ton programme si tu veux t'assurer des non-régressions, toute ton appli est dépendante de ta variable globale, et si tu veux utiliser plusieurs objets identiques, tu devras alors faire preuve de ruse pour pouvoir y accéder.

    Ce n'est pas vraiment développer durable .

    Passer le pointeur de ta structure, je ne vois pas ce qu'il y a du mal à ça.

  4. #4
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut
    @ Jérome, justement, c'est pour cette ruse que là que j'ai besoin d'aide ^^.

    En fait je vais essayer de mieux expliqué mon problème ^^.
    On imagine ma structure integer avec la variable i dedans

    On le construit puis a la fin on le détruit

    Pour l'afficher en c ++ on fait comme ceci

    integer.affiche();
    alors que en C on doit faire integer.affiche(integer);

    C'est là, au lieu de passer mon argument, que je veux savoir comment faire pour que la fonction "appartiennent vraiment" a mon objet, vous saisissez?

    J'avais penser a faire une variable globale, mais ça ne fonctionne que pour un seul objet, ça aurait éte trop facile sinon ^^

    Cordialement Qnope

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Impossible en C, le C n'est pas orienté objet, tu n'as donc pas le choix de spécifier un pointeur vers ta structure en argument à tes fonctions.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  6. #6
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut
    Je crois que je viens de trouver avec un tableau de globale, je sais que certains d'entre vous c'est le mal, mais vive le static ^^

    Merci quand même d'avoir essayer de m'aider

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par qnop Voir le message
    Je crois que je viens de trouver avec un tableau de globale, je sais que certains d'entre vous c'est le mal, mais vive le static ^^
    Effectivement, c'est une pratique qui serait bon de bannir, pour moi et voir d'autres, cela ne devrait même pas être autorisé par le compilateur
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Citation Envoyé par qnop Voir le message
    Je crois que je viens de trouver avec un tableau de globale, je sais que certains d'entre vous c'est le mal, mais vive le static ^^
    Voici quelques arguments pour te dissuader d'y recourir si ce n'est pas nécessaire :

    http://www.developpez.net/forums/d93...c/#post5271611

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par qnop Voir le message
    Citation Envoyé par Franck.H Voir le message
    Impossible en C, le C n'est pas orienté objet, tu n'as donc pas le choix de spécifier un pointeur vers ta structure en argument à tes fonctions.
    Hélas oui. et ça va même plus loin dans les contraintes.
    Si tu définis deux objets distincts, style "carre" et "rond", tu auras peut-être besoin de les afficher. Tu voudrais alors créer une fonction "affiche" qui servira à afficher le carré mais pour afficher le rond, tu ne pourras pas appeler la fonction "affiche" aussi. Tu seras obligé de trouver deux noms bien distincts pour tes fonctions, style "affiche_carre" et "affiche_rond".

    Bon, on s'y fait bien sûr. Mais quand on a goûté à l'objet, c'est dur de revenir au C...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Si tu définis deux objets distincts, style "carre" et "rond", tu auras peut-être besoin de les afficher. Tu voudrais alors créer une fonction "affiche" qui servira à afficher le carré mais pour afficher le rond, tu ne pourras pas appeler la fonction "affiche" aussi. Tu seras obligé de trouver deux noms bien distincts pour tes fonctions, style "affiche_carre" et "affiche_rond".
    Certes l'objet est moins évident en C, mais on peut quand même faire des choses biens, par exemple GTK+. (voir http://nicolasj.developpez.com/gobject/classe/)

  11. #11
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par Sve@r
    Si tu définis deux objets distincts, style "carre" et "rond", tu auras peut-être besoin de les afficher. Tu voudrais alors créer une fonction "affiche" qui servira à afficher le carré mais pour afficher le rond, tu ne pourras pas appeler la fonction "affiche" aussi. Tu seras obligé de trouver deux noms bien distincts pour tes fonctions, style "affiche_carre" et "affiche_rond".
    Ça peut ce faire en utilisant des pointeurs de fonction membre de la structure.

  12. #12
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    Ça peut ce faire en utilisant des pointeurs de fonction membre de la structure.
    Certes mais le pointeur ne pourra quand même pas pointer sur la même fonction, si elle est spécialisée dans le carré alors que tu veux afficher un rond (pour rester dans l'exemple précédent). Cela dit, rien ne t'empêche en effet de créer une fonction générique qui affiche différents objets par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef enum
    {
       TYPE_CARRE,
       TYPE_ROND,
     
       NB_TYPE
    }
    Type;
     
    void affiche (void * obj, Type type);

    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  13. #13
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    to : Franck.H
    Je ne comprend pas trop ce que tu veux dire, mais je me suis peut-être mal exprimé, du moins oublié une virgule.
    Ça peut ce faire en utilisant des pointeurs de fonction, membre de la structure.
    A la création de l'objet on fait pointer le pointeur sur la bonne fonction.
    ça impose bien sur de créer deux fonctions distinctes, par exemple affiche_rond et affiche_carre.

  14. #14
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    A la création de l'objet on fait pointer le pointeur sur la bonne fonction.
    ça impose bien sur de créer deux fonctions distinctes, par exemple affiche_rond et affiche_carre.
    Oui c'est sûr mais ca ne change rien au problème alors et c'est alourdir le code pour rien dans ce cas que de mettre un pointeur sur une fonction mais bon ce n'est que mon avis
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  15. #15
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Certe, mais quand on appelle affiche, il n'y a plus a se préoccuper si c'est un rond ou un carré.

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par qnop Voir le message
    Je crois que je viens de trouver avec un tableau de globale, je sais que certains d'entre vous c'est le mal, mais vive le static ^^
    Même en passant sur les problèmes liés à l'utilisation de variables globales, je ne vois pas trop en quoi ça résout ton problème. Il faudra bien passer l'index à utiliser à ta fonction, je ne vois pas où est le gain par rapport à passer un pointeur sur la structure adéquate.

  17. #17
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Points : 95
    Points
    95
    Par défaut
    En fait vous aviez raison, ça ne sers a rien, même avec les var globales, ce n'est pas possible(enfin je n'ai pas trouvé personnellement et pourtant j'ai chercher ^^)

    Merci de votre aide tout de même

    @Obsidian, merci pour l'explication sur les variables globales, je comprends pourquoi ce n'est pas terrible

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Oui c'est sûr mais ca ne change rien au problème alors et c'est alourdir le code pour rien dans ce cas que de mettre un pointeur sur une fonction mais bon ce n'est que mon avis
    Avec le pt de fonction on peut faire de l'héritage et du polymorphisme .

  19. #19
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par Anonymouse Voir le message
    Avec le pt de fonction on peut faire de l'héritage et du polymorphisme .
    Je vois à peu prêt comment faire de l'héritage, mais peux tu donner un exemple pour le polymorphisme ?

  20. #20
    Membre à l'essai
    Inscrit en
    Décembre 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 14
    Points : 11
    Points
    11
    Par défaut polymorphisme
    pour le polymorphisme en c je pense chacun a sa maniere moi je vais te presenter la mienne peut-etre qu'elle n'est pas parfaite mai sa te donnera des idées:

    prenons un exemple simple concernant les animaux, nous allons creer la classe de base;

    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
     
    typedef struct animal animal;
    struct animal
    {
       /* < les accesseurs >*/
       void   (*Set_child)(struct animal*,void*);
       void  (*Set_child_name)(struct animal*,char*)
     
       /* < les methodes virtuelle >*/
        void (*Crie)(struct animal*);
     
       /* < private >*/
       void* child;
       char* child_name;
    };
    typedef struct animal* Animal;
    maintenant nous allons deriver cette classe en toute sous classe animal de notre choix mais on va prendre que le chat et chien de bon vieux amis

    on cree la classe chien dans un nouveau fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    typedef struct chien chien;
    struct chien
    {
       /* methodes public >*/
     
       /* < private >*/
       struct animal* parent;
       char* name;
    };
    typedef struct chien* Chien;
     
    struct animal* Chien_new(char*);
    void               Crie_de_chien(struct animal*);

    voici comment s'elaborera les constructeurs des sous classes
    dans chien.c
    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
     
    static void Chien_init(Chien);
     
    Animal Chien_new(char* name)
    {
      chien* tthis = malloc(sizeof *tthis);
      // on realise un test i sa echoue
     
      Chien_init(tthis);
     
      tthis->name = name;
     
      return tthis->parent;
    }
    /*************************/
     
    // c'est ici que les pointeurs de structure vont nous permettre de faire du polymorphisme
     
    static void Chien_init(Chien tthis)
    {
      animal* parent = Animal_new();
      parent->Crie    = crie_de_chien;
      parent->Set_child_name(parent,"Chien");
     
      tthis->parent = parent;
     
     parent->Set_child(parent,tthis);
    }
    /****************/
     
    void crie_de_chien(Animal parent)
    {
      printf("\nAboie; woah woah Grrrrr!!!!\n");
    }
    ainsi on fait de meme pour les chat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct chat chat;
    struct chat
    {
       /* < private >*/
     
       struct animal* parent;
       char* name;
    };
    typedef struct chat* Chat;
     
    struct animal* Chat_new(char*);
    void               Crie_de_chat(struct animal*);
    dans chat.c

    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
     
    static void Chat_init(Chat);
     
    Animal Chat_new(char* name)
    {
      chat* tthis = malloc(sizeof *tthis);
      // on realise un test si sa echoue
     
      Chat_init(tthis);
     
      tthis->name = name;
     
      return tthis->parent;
    }
    /*************************/
    static void Chat_init(Chat tthis)
    {
      animal* parent = Animal_new();
      parent->Crie    = crie_de_chien;
      parent->Set_child_name(parent,"Chat");
     
      tthis->parent = parent;
     
     parent->Set_child(parent,tthis);
    }
    /****************/
    void crie_de_chat(Animal parent)
    {
      printf("\nMiaule; mian mian...\n");
    }
    et voila le tour es joué dans le main ca se presente comme ceci

    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
     
     int main()
    {
      Animal Rex = NULL;
      Animal Minou = NULL;
     
     Rex = Chien_new("Rex");
     Minou = Chat_new("Minou");
     
     Rex->Crie(Rex);
     Minou->Crie(Minou);
     
     Rex->Delete(Rex);
     Minou->Delete(Minou);
     
    return 0;
    }
    voici comment on peu faire du polymorphisme en C

    biensur pour utiliser les methode publics des sous classes on fera un define dans la classe de base exemple

    les sous classe chien et chat on une methode membre "Attaquer"

    pour pouvoir y acceder on fera ceci

    CHIEN(Rex)->Attaquer(Rex,Minou);
    ou
    CHAT(Minou)->Attaquer(Minou,Rex);

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

Discussions similaires

  1. [PHP 5.0] optimisation fonctions POO
    Par domega dans le forum Langage
    Réponses: 2
    Dernier message: 07/10/2009, 13h15
  2. Réponses: 3
    Dernier message: 06/11/2005, 18h02
  3. [POO] passage nom objet dsn les parametres d'une fonction
    Par melou dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/10/2005, 17h26
  4. [POO] fonction toUpperCase : Objet attendu
    Par LineLe dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 19/04/2005, 16h51
  5. [POO] Formulaire HTML + fonction JS = Erreur
    Par bdaboah dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 23/11/2004, 21h59

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