2010-03-02 3 views
1

Mon application utilise un int comme identifiant pour identifier les objets dans le registre en mémoire et le registre permanent. Les fonctions de l'application reçoivent l'ID en tant qu'argument, extraient l'objet du registre et font leur travail, par ex. L'application a évolué et il est maintenant possible d'avoir plus d'un registre dans la même application. L'application utilise maintenant un registre «courant» globalement accessible, ce qui, comme le font généralement les globales, cause beaucoup de problèmes. Pour se débarrasser du concept d'un registre global 'courant', je devrais introduire un type qui identifie de manière unique l'objet à travers les registres. Je ne peux pas changer la valeur du int qui est utilisé, donc je dois créer un type full_id à partir de l'ID int et une identification du registre. La fonction exemple aurait donc devoir changer deRefactorisation d'un type d'ID

void print(full_id id, int bar, double zip, int boo) 
{ 
    Object *obj = get_obj_by_id(id); 
    obj->print(bar, zip, boo); 
} 

Il existe des conventions sur la désignation des arguments d'identité, mais ceux-ci ne sont pas rigoureusement suivies dans toute l'application, je ne peux pas faire des hypothèses sur le nom de l'argument id, ou que c'est toujours le premier argument. De plus, il y a beaucoup de nombreuses fonctions qui doivent être changées. Quelle est la manière la plus efficace et la plus fiable de remplacer les ID typés int par full_id?

Répondre

0

Je commencerais à chercher tous les appels à get_obj_by_id et changer son argument de int à full_id. Ensuite, compilez, et voyez ce qui ne compile pas, et répétez ceci itérativement jusqu'à ce que vous ayez trouvé tous les endroits. Lent, mais ça va marcher.

4

Vraisemblablement votre nouveau type n'est pas numérique - c'est quelque chose comme un petit struct?

typedef struct _full_id { 
    int registry_id; 
    int object_id; 
} full_id; 

Si oui, alors vous pouvez commencer en changeant vos fonctions de bas niveau qui traitent des ID - comme la fonction get_obj_by_id() dans votre exemple. Après avoir modifié cette fonction pour prendre un paramètre full_id au lieu d'un int, recompilez le programme complet. Tous les sites d'appel qui appellent cette fonction doivent maintenant signaler une erreur due à l'incompatibilité de type - vous pouvez alors aller à ces sites d'appel et fixer leurs types de paramètres. Rincez, répétez, et finalement vous les aurez toutes réparées.

Bonne chance (et je parie que vous le souhaitez, vous avez utilisé un typedef pour commencer, maintenant,?)

+0

+1 pour mentionner que typedef aurait résolu le problème beaucoup plus facile. – Patrick

1

La façon la plus fiable: assurez-vous que vous ne pouvez pas convertir implicitement un entier à full_id. Ensuite, changez l'argument en get_obj_by_id en full_id, et laissez le compilateur travailler là où vous devez changer les choses.

Il est plutôt inefficace, mais très fiable (sauf pour les erreurs humaines) ..

0

Si vous avez le contrôle sur l'allocation d'identité, vous pourriez allouer une certaine gamme d'identifiants pour certains registres et dans get_obj_by_id() pour décider registre à adresser.

Exemple:

Object* get_obj_by_id(int id) 
{ 
    if(id % 2) 
     return registry1[id]; 
    else 
     return registry2[id]; 
}