2010-10-28 3 views
3

Donc, j'ai du mal à trouver comment surmonter cela.Réutilisation même c ADT pour les autres types

Prenez par exemple, j'ai une mise en œuvre de l'arbre rouge noir qui fonctionne avec des objets:

typedef unsigned long int Key; 
struct rbt_node{ 
    Item item; 
    int color; 
    Key key; 
    struct rbt_node* parent; 
    struct rbt_node* left; 
    struct rbt_node* right; 
}; 

puis dans un Item.hi définir la structure que je vais utiliser, par exemple:

typedef struct _something* Item; 

De cette façon, je découplage l'élément détenu de l'implémentation de l'arborescence. Le problème se pose si je veux réutiliser l'ADT pour d'autres types.

Au moment où je devrais définir un Item2.h, et copier rbt.c/rbt.h à rbt2.c/rbt2.h et les changer pour utiliser Item2.h et changer les noms de fonctions. N'y a-t-il pas une manière plus propre?

J'ai trouvé ce C double linked list with abstract data type, mais il semble y avoir quelques problèmes selon l'architecture et la taille des structures, que je ne connais pas vraiment très bien.

Je suis à la recherche de ce type d'utilisation:
rbt_insert(rbt_of_something, something);
rbt_insert(rbt_of_somethingElse, somethingElse);

Merci

+1

Avec certains fichiers d'en-tête et le préprocesseur, vous pouvez imiter des modèles. – leppie

+1

Dans la toute dernière réponse à la question que vous avez liée à vous trouver des liens sur la façon dont ces choses sont faites dans le noyau Linux. Je pense que c'est une très bonne lecture pour ce type de stratégies. –

+0

@Jens Gustedt Il semble intéressant et une excellente ressource, je vais devoir jeter un oeil. Merci – GriffinHeart

Répondre

2

Créer un élément void*. Définissez ensuite les fonctions ou les macros que vous utilisez pour affecter/lire les éléments afin d'effectuer les conversions requises. par exemple.

FILE* rbt_fileFromNode(struct rbt_node* node); 

Si vous voulez être vraiment intelligent et vous avez un nombre fixe de types que vous souhaitez mettre là-dedans, ajouter un ENUM à rbt_node ou rbt_tree pour stocker le type de l'élément.

+0

Je me suis retrouvé pour cette solution. Implémenté rbt avec des vides, puis fait .h avec des macros pour gérer les castings pour chaque type nécessaire. – GriffinHeart

3

Vous pouvez mettre toutes vos définitions d'articles dans un fichier d'en-tête unique et utiliser préprocesseur de choisir la bonne:

#ifdef SOMETHING 
typedef struct _something* Item; 
#elif SOMETHINGELSE 
typedef struct _somethingElse* Item; 
#else 
#error no definition for Item. Use -D flag to specify Item definition. 
#endif 

Ensuite, lors de la compilation, utilisez simplement les arguments -D pour définir l'une de ces macros.

+0

Vous souhaitez probablement utiliser des macros push/pop à la place, vous pouvez donc utiliser plus d'un type lors de la compilation. – leppie

+0

Je ne vois pas comment cela me permet d'utiliser la même implémentation rbt pour 2 types d'éléments différents dans le même fichier. Pourriez-vous élaborer? – GriffinHeart

+0

@GriffinHeart: utilisez des macros push/pop, ou utilisez '# undef' après avoir inclus l'en-tête, puis définissez le suivant, et ainsi de suite. – leppie

Questions connexes