سؤال
إذا كان يجب تحديد نوع المتغير على أنه وقت تشغيل في C ولكن تم إصلاح الاسم المتغير وإعطاءه ، هل هناك أي طريقة لإعادة استخدام الكود الذي يتضمن المتغير؟
في الواقع أنا أسأل عن وضع نظير C وقت التشغيل تحديد نوع C ++.
إذا أمكن ، يرجى إعطاء بعض الأمثلة.
المحلول
لا تحتوي لغة C على الميزات الموجهة للكائنات التي تجعل من المفيد أن تسأل عن نوع وقت التشغيل للكائن في C ++.
عادةً ما تنفذ generity في C عن طريق الصب من وإلى void*
. مثال: وظيفة C QSort.
إذا كان سؤالك يتعلق بتحديد وقت التشغيل ، فما هو النوع A الفعلي void*
يشير المؤشر إلى ، هذا مستحيل. يتم ببساطة عدم تخزين المعلومات على الإطلاق من قبل معظم المجمعين.
نصائح أخرى
تتمثل إحدى التقنيات القياسية في توفير متغير معلومات النوع السريع كمعلمة وتبديل ذلك ، وتمرير جميع البيانات بالرجوع إليها. داخل الوظيفة ، نقوم باسترداد القيمة مع الصب الصريح. لا يتم تحديد نوع void* بواسطة برنامج التحويل البرمجي ، لذا فإن الخطر يرسل نوعًا غير معلوم من الوظيفة (خطأ التجزئة أو فساد البيانات أو نتيجة سلوك غير معروفة). ابدأ بإعداد تعداد الأنواع التي تحتاجها:
في هذه الحالة ، أستخدم type_function الاتفاقية لتمثيل دالة لإرجاع نوع.
يختار توجيه ENUM أعداد صحيحة متتالية من 0 ، أو يمكنك تعيين كل تعداد قيمة 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* );
في تعريف الوظيفة الخاص بك ، ترسل كل من البيانات بالرجوع والنوع ويلميها إلى النوع الصحيح قبل الاستخدام:
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;
}
كما قد تخمن ، هذا يلعب مع المباريات في مصنع الألعاب النارية ، ولا يتم تشجيعه كممارسة مستمرة.
في الكود الخاص بك ، ستسميه مثل هذا:
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 ... */
بخلاف وظيفة لمرة واحدة ، توصي باستخدام وظائف Varargshttp://www.eskimo.com/~scs/cclass/int/sx11b.html