سؤال

ربما يكون هذا تكرارًا معتادًا للبرمجة.لقد لاحظت DECLSPEC_NOVTABLE ( __declspec(novtable)) على مجموعة من الواجهات المحددة في الرؤوس:

struct DECLSPEC_NOVTABLE IStuff : public IObject
{
    virtual method1 () = 0;
    virtual method2 () = 0;
};

ال مقالة MSDN في هذه السمة الموسعة __declspec تقول أن إضافة هذا الشخص ستؤدي إلى إزالة إدخالات vtable الخاصة بالبناء والتفكيك وبالتالي يؤدي إلى "تقليل كبير في حجم الكود" (لأنه ستتم إزالة vtable بالكامل).

هذا لا معنى له بالنسبة لي.هؤلاء الأشخاص افتراضيون تمامًا، فلماذا لا يقوم المترجم بذلك بشكل افتراضي؟

تقول المقالة أيضًا أنه إذا قمت بذلك، ثم حاولت إنشاء مثيل لأحد هذه الأشياء، فسوف تحصل على انتهاك وصول وقت التشغيل.ولكن عندما حاولت ذلك مع عدد قليل من المترجمين (مع أو بدون ملحق __declspec)، لم يقوموا بالترجمة (كما كنت أتوقع).

لذلك أعتقد أن تلخيص:

  • هل يقوم المترجم بإزالة vtable بغض النظر عن الواجهات الافتراضية البحتة، أم أنني فاتني شيئًا أساسيًا هنا؟
  • ما الذي تتحدث عنه مقالة MSDN؟
هل كانت مفيدة؟

المحلول

يقوم المترجم بإزالة مرجع فقط إلى vtable، والذي كان من الممكن أن يكون أثناء إنشاء الفصل.لذلك، يمكن للرابط تحسينه بعيدًا حيث لم يعد هناك مرجع له في التعليمات البرمجية.

بالمناسبة أيضًا، لقد اعتدت على الإعلان عن مُنشئ فارغ كـ protected, وأيضًا باستخدام امتداد Microsoft abstract الكلمة الأساسية، لتجنب انتهاك الوصول في وقت التشغيل.بهذه الطريقة، يكتشف المترجم المشكلة في وقت الترجمة بدلاً من ذلك (نظرًا لأن الفئة الأساسية فقط هي التي يمكنها إنشاء مثيل للواجهة من خلال المنشئ المحمي).بالطبع سوف تقوم الفئة المشتقة بملء vtable أثناء إنه بناء.

نصائح أخرى

إنه جزء من التعامل مع مترجم/رابط غبي.يجب على المترجم عدم إدراج أي مرجع لهذا الجدول vtable، لأنه من الواضح تمامًا أنه ليست هناك حاجة لهذا الجدول vtable.يمكن للمترجم أيضًا وضع علامة على المرجع بطريقة تمكن الرابط من حذف vtable، لكن هذا أكثر تعقيدًا بالطبع.

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