2010-01-15 5 views
4

Si le type d'une variable doit être déterminé en tant qu'exécution en C mais que le nom de la variable est fixe et donné, y a-t-il un moyen de réutiliser le code impliquant la variable?runtime détermine le type pour C

En fait, je pose des questions sur la situation de la contrepartie C de runtime determine type for C++.

Si possible, veuillez donner quelques exemples.

Répondre

7

Le langage C ne possède pas les fonctionnalités orientées objet qui permettent de poser des questions sur le type d'exécution d'un objet en C++.

Vous appliquez généralement la généricité en C par coulée vers et à partir de void*. Exemple: the C function qsort.

Si votre question concerne la détermination au moment de l'exécution du type de pointeur void*, cela est impossible. Les informations ne sont simplement pas stockées du tout par la plupart des compilateurs.

1

Une technique standard consiste à fournir une variable info de type rapide en tant que paramètre et de l'activer, puis de transmettre toutes les données par référence. à l'intérieur de la fonction, nous récupérons la valeur avec un casting explicite. Le type void * n'est pas coché par le compilateur, de sorte que le danger envoie un type qui n'est pas géré par la fonction (erreur de segmentation, corruption de données ou résultat de comportement inconnu). Commencez par configurer une énumération des types dont vous avez besoin:

Dans ce cas, j'utilise la convention TYPE_FUNCTION pour représenter une fonction renvoyant un type.

La directive enum choisit des entiers successifs à partir de 0, ou vous pouvez attribuer à chaque énumération sa propre valeur int.

typedef enum D_types { 
ANINT, // don't use actual system type names 
AFLOAT, 
ADOUBLE, 
ASTRING, 
MY_STRUCT=100, 
MY_STRUCT2=200 
VOID_FUNCTION=1000, 
INT_FUNCTION = 2000, 
STRUCT_FUNCTION=3000 
} DATATYPE; 

/* an f_int is a function pointer to a function */ 
typedef int (*f_int)(int, void*); 

Dans votre définition de la fonction que vous envoyez à la fois les données de référence et le type et jette le type correct avant utilisation:

int myfunction (DATATYPE dt, void* data, ) 
{ 
    int an_int = 0; 
    int * ip; // typed pointers for casting of the void pointer data 
    double * dp; 
    char * sp; 
    struct My_struct * msp; 
    struct My_struct_2 * ms2p; 
    f_int fp; 
    ... 

    switch (dt){ 
    case ANINT: 
     ip = (int*) data; // only pointers can be assigned void pointer values. 
     int i = *ip  // dereference of typed pointer, no dereferencing void pointers. 
     ... 
     break; 
    case ADOUBLE: 
     dp = (double*) data; 
     double d = *dp; 
     ... 
     break; 
    case ASTRING: 
     char * s = strdup((char*) data); // cast to char pointer allowed (pointer->pointer) 
     ... 
     break; 
    case MY_STRUCT: 
     msp = (struct My_Struct *) data; 
     char* ms_name = msp->name; // if my_struct has a name string ... 
     float dollarvalue = msp->dvalue; 
     ... 
    case INT_FUNCTION: 
     fp = (f_int)data; 
     an_int = fp(ANINT, 5); 
    } 
return an_int; 
} 

Comme vous pouvez le deviner, ce joue avec des allumettes dans une usine de feux d'artifice, et pas encouragé comme une pratique constante.

dans votre code que vous appelez comme ceci:

double pi =3.14159; 
int g = myfunction(ADOUBLE, &pi ); // pass by reference, not value 

int j = myfunction (ASTRING , "HEY NOW"); //C strings pass by ref normally 



f_int myfunc = myfunction; // a function pointer (ref to the functions address) 

int r = myfunction (INT_FUNCTION, myfunc); /* function as a parameter ... */ 

Autre que pour une fonction unique il est recommandé d'utiliser les fonctions varargs http://www.eskimo.com/~scs/cclass/int/sx11b.html

Questions connexes