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 :

Un seul code pour 2 types de struct : pseudo-polymorphisme ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut Un seul code pour 2 types de struct : pseudo-polymorphisme ?
    Bonjour à tous,

    Je travaille en ce moment sur un programme (C bien sûr) qui est amené à géré deux types de structure de données assez différentes, mais qui applique les mêmes opérations sur ces structures.
    Je sais qu'en C, il n'existe pas de polymorphisme vu que la notion d'objet n'existe pas, et donc pour appliquer une opération sur deux structs différents, je devrais écrire deux méthodes différentes, chacune s'appliquant à un type de struct.
    Cependant ... je me demandais s'il existe un moyen de faire un pseudo-polymorphisme pas trop moche. J'aimerais pouvoir écrire une seule fois une fonction qui s'applique donc aux deux types de structs, comme ceci :

    - J'appelle ma fonction qui prend en paramètre un pointeur type void (parce-que type inconnu) sur mon struct
    - La fonction "reconnait" le type du struct parmi les deux types possibles
    - En fonction du type "reconnu", elle applique tel ou tel opération

    Je ne sais pas si je suis super clair dans mes explications. Le but est de savoir s'il existe un moyen d'écrire une opération s'appliquant sur deux types de struct différents sans jamais avoir a stocker dans le programme "le struct X situé à cet adresse est de type Y".

    Ce lien parait correspondre à ce que je cherche :
    http://sky13.blogspot.de/2007/06/pse...isme-en-c.html

    Cependant, il est écris qu'il ne faut pas abuser de ce type d'astuce. Quelqu'un m'a aussi dit qu'il existait une astuce à base de macro, sans pouvoir m'en dire plus ...

    Qu'en pensez-vous ? Avez vous des pistes ?
    Merci encore de votre aide !

  2. #2
    Membre très actif

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

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 587
    Par défaut
    Bonjour,

    je suis preneur si il existe une solution, car je ne voit pas comment le comment on peut faire pour qu'une fonction détecte le "type" d'un void* sans faire de cast...

    Tu peux peut-être décrire le type dans les 4 premiers octets pointée par le void*, mais c'est non portable et dégueulasse

  3. #3
    Membre très actif

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

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 587
    Par défaut
    Sinon utiliser une structure contenant les deux structures.
    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
     
    typedef enum
    }
        OBJECT1,
        OBJECT2,
    }objects;
    typedef struct
    {
        int i;
    }object1_t;
    typedef struct
    {
        char str[32];
    }object2_t;
     
    typedef struct
    {
        objects type;
        object1_t obj1;
        object2_t obj2;
    }container_t;
     
     
    void operation(void * const this)
    {
        container_t * const container = (container_t *)this;
        switch(container->type)
        {
        case OBJECT1 : printf("%d\n",container->obj1.i);
        case OBJECT2 : printf("%s\n",container->obj2.str);
        default:{}
        }
    }
    Pas très pratique c'est vrai.

  4. #4
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut
    Effectivement, ça a été ma première idée, celle qui parait la plus logique. Mais comme tu dis, c'est dégueu et non-portable Et du coup, je stock en mémoire de l'information plus ou moins "inutile" : pour chaque struct je dois stocker aussi son type. Mon programme doit être très performant au niveau de la gestion mémoire (je suis au bit près pour ne rien te cacher), c'est pour ça que je préférerais (si possible) une solution où je déduis l'information plutôt que de la stocker, quitte à ce que le code soit un peu dégueu mais que ça marche (et que ce soit portable).
    Merci pour ta réponse !

  5. #5
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut
    Ouch, utiliser une structure contenant les deux structures mène vraiment à une utilisation sous-optimale de la mémoire je pense. Je pense que la solution qui est dans mon premier post serait "meilleur" dans le sens où elle demande plus de ligne de code, et peut-être un temps d'exécution plus long, mais pas plus de mémoire.

    Merci encore pour ta réponse

  6. #6
    Membre très actif

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

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 587
    Par défaut
    Ouch, utiliser une structure contenant les deux structures mène vraiment à une utilisation sous-optimale de la mémoire je pense
    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
     
    typedef struct
    {
        objects type;
        object1_t * obj1;
        object2_t * obj2;
    }container_t;
     
     
    void operation(void * const this)
    {
        container_t * const container = (container_t *)this;
        switch(container->type)
        {
        case OBJECT1 : printf("%d\n",container->obj1->i);
        case OBJECT2 : printf("%s\n",container->obj2->str);
        default:{}
        }
    }

  7. #7
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut
    Je met cette solution de côté, merci

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Au lieu de grouper dans une structure les deux objets, il serait déjà plus économique en mémoire de les placer en union.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/07/2014, 17h21
  2. Un seul code pour toutes les feuilles
    Par NEC14 dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 16/05/2013, 16h46
  3. Un seul code pour tous
    Par Stalk3R dans le forum jQuery
    Réponses: 8
    Dernier message: 08/04/2012, 09h42
  4. Réponses: 1
    Dernier message: 28/10/2006, 09h43
  5. Réponses: 2
    Dernier message: 01/04/2003, 22h09

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