كيف يمكن للمرء تنفيذ وظائف افتراضية C ++ في C [مكررة

StackOverflow https://stackoverflow.com/questions/3113583

  •  29-09-2019
  •  | 
  •  

سؤال

توفر لغة C ++ virtual المهام. ضمن قيود تنفيذ لغة C الخالصة ، كيف يمكن تحقيق تأثير مماثل؟

هل كانت مفيدة؟

المحلول

سرقت من هنا.

من فئة C ++

class A {
protected:
    int a;
public:
    A() {a = 10;}
    virtual void update() {a++;}
    int access() {update(); return a;}
};

يمكن اشتقاق جزء رمز C. وظائف الأعضاء الثلاثة C ++ من class A يتم إعادة كتابتها باستخدام رمز خارج الخط (مستقل) وجمعه بواسطة العنوان في بنية مسماة A_functable. أعضاء البيانات من A ويقترن مع جدول الوظائف في بنية C المسمى A.

struct A;

typedef struct {
    void (*A)(struct A*);
    void (*update)(struct A*);
    int (*access)(struct A*);
} A_functable;

typedef struct A{
    int a;
    A_functable *vmt;
} A;

void A_A(A *this);
void A_update(A* this);
int A_access(A* this);

A_functable A_vmt = {A_A, A_update, A_access};

void A_A(A *this) {this->vmt = &A_vmt; this->a = 10;}
void A_update(A* this) {this->a++;}
int A_access(A* this) {this->vmt->update(this); return this->a;}

/*
class B: public A {
public:
    void update() {a--;}
};
*/

struct B;

typedef struct {
    void (*B)(struct B*);
    void (*update)(struct B*);
    int (*access)(struct A*);
} B_functable;

typedef struct B {
    A inherited;
} B;

void B_B(B *this);
void B_update(B* this);

B_functable B_vmt = {B_B, B_update, A_access};

void B_B(B *this) {A_A(this); this->inherited.vmt = &B_vmt; }
void B_update(B* this) {this->inherited.a--;}
int B_access(B* this) {this->inherited.vmt->update(this); return this->inherited.a;}

int main() {
    A x;
    B y;
    A_A(&x);
    B_B(&y);
    printf("%d\n", x.vmt->access(&x));
    printf("%d\n", y.inherited.vmt->access(&y));
}

أكثر تفصيلا من الضرورة ، لكنه يحصل على النقطة.

نصائح أخرى

gcc .... يتم الإعلان عن وظيفة افتراضية في الفئة الأساسية للكائن ومن ثم يتم "تجاوزها" أو تنفيذها في الفئات الفرعية. أي ، قل أن لديك فئة قاعدة مركبة وأنك تقوم بإنشاء فئتين فرعيتين ، دراجة نارية ، والسيارات. ستعلن الفئة الأساسية عن وظيفة افتراضية لـ AddTires () ثم تنفذ الفئات الفرعية هذه الوظيفة وستقوم كل فئة فرعية بتنفيذها بشكل مختلف. تحتوي السيارة على 4 عجلات ، حيث تحتوي دراجة نارية على 2. لا يمكنني أن أعطيك بناء الجملة لـ C أو C ++ ، على الرغم من. أتمنى أن يساعدك هذا

الوظائف الافتراضية هي ميزة في اتجاه كائن C ++. إنهم يشيرون إلى الطرق التي تعتمد على مثيل كائن معين بدلاً من النوع الذي تحمله حاليًا.

وبعبارة أخرى: إذا قمت بتسهيل كائن على أنه شريط ، ثم ألقيته على FOO ، فستظل الأساليب الافتراضية هي تلك التي كانت عليها في مثيل (محدد في الشريط) ، في حين أن الأساليب الأخرى ستكون من Foo.

عادة ما يتم تنفيذ الوظائف الافتراضية عن طريق VTABLES (هذا بالنسبة لك لإجراء المزيد من الأبحاث حول ؛)).

يمكنك محاكاة أشياء مماثلة في C باستخدام الهياكل ككائنات الرجل المسكين وتوفير مؤشرات الوظيفة فيها.

(بشكل أكثر صوابًا ، تجعل الوظائف غير الذروة غامضة في الفئة التي يجب أن تؤخذ منها الطريقة ، لكن في الممارسة العملية ، أعتقد أن C ++ يستخدم النوع الحالي.)

هنا هو وصف للوظائف الافتراضية.

لا توجد وسيلة لتنفيذ وظائف افتراضية في Clain C ، لأن C ليس لديه فكرة عن الميراث.

تحديث:كما هو موضح في التعليقات أدناه ، من الممكن القيام بشيء مشابه للوظائف الافتراضية في C على التوالي باستخدام الهياكل وتأسيس الوظائف. ومع ذلك ، إذا كنت معتادًا على لغة مثل C ++ لها وظائف افتراضية "حقيقية" ، فمن المحتمل أن تجد تقريب C أقل أناقة وأصعب في الاستخدام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top