سؤال

لماذا مثلا لا يوجد دعم اللغة لدراسة vtable?لماذا لا أستطيع استبدال وظيفة عضو جديد ؟ لدي شعور أن هناك طرق لوضع هذه الميزات على حسن استخدامها.

هل هناك أي اللغات الأخرى هناك التي تسمح لي أن أفعل مثل هذه الأشياء ؟

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

المحلول

والسبب الرئيسي هو أن الحفاظ vtable كما تفصيل تطبيق يسمح لأي التنفيذ الملموس لتحسين ذلك حسب ما يراه مناسبا. هذا يعني أنه يمكن على سبيل المثال تقليم أو حتى القضاء vtable تماما إذا كان يمكن إثبات أنه لا توجد مكالمات افتراضية لطريقة معينة (أو جميع الطرق). أو أنها قد تحل محل برقية vtable مع لو-آخر نوع الاختيار إذا على سبيل المثال انها ترى انه لا يوجد سوى عدد قليل من البدائل (هذا يمكن أن يكون مفيد لالتنبؤ فرع ستعمل في هذه الحالة، ولكن ليس مع vtables، وأيضا لأنه إذا كان بين آخر ومن ثم يمكن inlined فروع). ويمكن أن إعادة ترتيب الأساليب في vtable بحيث دعا الأكثر شيوعا تلك التي تأتي في وقت سابق، أو مثل تلك التي تسمى عادة الحق واحدا تلو الآخر ملء فتحات المجاورة في vtable للاستفادة من التخزين المؤقت. وهلم جرا وهكذا دواليك. بطبيعة الحال، فإن كل هذه التطبيقات أيضا جعل تخطيط vtable لا يمكن التنبؤ به تماما، وبالتالي لا طائل منه، إذا كان ليتعرض (من قبل المواصفات اللغة) لتنفيذها.

وكذلك، vtables ليست بسيطة كما أنها سليمة أن يكون. على سبيل المثال، غالبا ما يكون المجمعين لتوليد thunks لإصلاح ما يصل مؤشر this لأشياء من هذا القبيل الميراث الظاهري، أو وراثة متعددة جنبا إلى جنب مع أنواع عودة التغاير. هذا هو مرة أخرى وهو الأمر الذي لم يكن لديك "أفضل طريقة واحدة" للقيام بذلك (وهذا هو السبب المجمعين مختلفة تفعل ذلك بشكل مختلف)، وتوحيد ذلك يتطلب فعال يستقر على طريقة معينة.

وقال ان "التحول vtable" هو أسلوب يمكن أن تكون مفيدة إذا تعرضت بوصفها بناء على مستوى أعلى (بحيث أمثل ما زال ممكنا). للحصول على مثال، انظر UnrealScript، والذي يسمح احد لتحديد عدة للفئة (افتراضية واحدة، وغيرها اسمه)، وتجاوز بعض الأساليب في الدول مسمى. يمكن اشتقاق الفئات تجاوز أساليب أكثر في الدول القائمة، أو إضافة دولهم وتجاوز فيها. وعلاوة على ذلك، يمكن للدول تمتد دول أخرى (حتى إذا لم يتم تجاوز أسلوب لدولة معينة، فإنه يرتد إلى الدولة "الأم"، وهلم جرا حتى تصل سلسلة الحالة الافتراضية). لنمذجة الممثل (الألعاب التي هي أساسا) كل هذا يجعل الكثير من المعنى، وهذا هو السبب UnrealScript لديه. وآلية تنفيذ فعالة واضحة لكل هذا هو التحول vtable، مع كل دولة لها vtable منفصل.

نصائح أخرى

ولأنه هو التفاصيل تنفيذ مترجم. قد يغير ذلك التنفيذ، وأي التعليمات البرمجية التي تعتمد على أن يكون هشا في أحسن الأحوال.

وC ++ هي لغة حيث يمكنك أبدا "دفع ثمن" ما كنت لا تستخدم. وهذا النوع من وقت التشغيل دعم تشغيل يتعارض مع تلك الفلسفة.

وهناك الكثير من لغات (على الطرف أكثر ديناميكية من الطيف) التي تدعم ذلك.

لأنه لا بد من تنفيذها باعتبارها VTable، على الرغم من أن هذا هو الحال عادة. باختصار، لا يوجد شيء من هذا القبيل كما VTable في C ++!

وجافا سكريبت، بيثون، وروبي يمكن أن نفعل كل هذا. في تلك اللغات، والطبقة والمثال التعاريف هي قابلة للتغيير في وقت التشغيل. تجريدي، كل كائن ونوع هو قاموس من المتغيرات عضو والأساليب التي يمكن فحصها وتحديثها.

وهذا غير ممكن في C ++ لأن ذلك يتطلب أن تكون قادرة على إعادة كتابة إنشاء التعليمات البرمجية ثنائي، والتي يمكن تحمل تكلفة أداء كبيرة.

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

للأسف (أو غير ذلك، اعتمادا على وجهات نظركم بشأن هذه المسألة ؛-)، لم يتم تصميم C ++ لدعم قرد الترقيع. في بعض الحالات (مثل COM) في vtable هو جزء من تنفيذ وكنت قد تكون قادرة على كزة حول وراء الكواليس. ومع ذلك، لن تكون معتمدة من هذا أو المحمولة.

وأعتقد أنك يمكن أن تفعل أشياء من هذا القبيل في لغات ديناميكية مثل بايثون:

>>> class X():
...     def bar(self): print "bar"
...     
>>> x = X()
>>> x.bar()
bar
>>> def foo(x): print "foo"
... 
>>> X.bar = foo
>>> x.bar()
foo

والفرق مع لغة ثابتة مثل C ++ هو أن المترجم بالبحث عن أسماء في وقت التشغيل ومن ثم تقرر ما يجب القيام به.

في C ++ هناك حلول أخرى المحتمل إلى "استبدال دالة عضو مع آخر" المشكلة أبسط التي قد تستخدم مؤشرات الدالة:

#include <iostream>

class X;
typedef void (*foo_func)(const X&);

void foo(const X&) { std::cout << "foo\n"; }
void bar(const X&) { std::cout << "bar\n"; }

class X
{
    foo_func f;
public:
    X(): f(foo) {}
    void foobar() { f(*this); }
    void switch_function(foo_func new_foo) { f = new_foo; }
};

int main()
{
    X x;
    x.foobar();
    x.switch_function(bar);
    x.foobar();
}

و(فو وشريط لا تستخدم X & حجة، في هذا المثال، على غرار المثال بايثون)

وأنا أعمل على لغة مترجمة بشكل ثابت أن يفضح vtable، وصدقوني أنه لا بأس به من <لأ href = "http://www.jargon.net/jargonfile/h/hairy.html" يختلط = "نوفولو noreferrer"> الشعر لفضح.

  • أي شيء يمكنك القيام به في C++, يمكنك القيام به في مباشرة ج مع القليل من كدح.
  • أي متواضعة ومعقولة برنامج C يجب أن تجمع في C++.

ربما ما تريد لتنفيذ الخاصة بك vtables دون استخدام C++'s المدمج في المرفق.سيكون لديك الكثير من المرح مع المؤشر إلى الأعضاء-وظائف (ptmf هو)!

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

<اقتباس فقرة>   

هل هناك أي لغة أخرى خارج   هناك والتي تسمح لي أن تفعل مثل هذا   الأشياء؟

الهدف-C (والهدف-C ++ أيضا) يسمح استبدال وقت التشغيل أساليب جمعها بالفعل. انها إما أفضل مزيج من تقنيات والدينامية أو أسوأ، وهذا يتوقف على من تسأل.

وكما أشار آخرون، لا يوجد مفهوم المعيار "vtable" في C ++، وانها مجرد تقنية التنفيذ على الصعيد العالمي تقريبا، مثل الكثير من اسم تغيير اسم.

إذا كنت تبحث عن أن تكون قادرة على إعادة تعريف وظائف على الطاير في لغة مترجمة، قد تكون مهتمة في اللثغة المشتركة. هناك ويجب أن يكون الآخرين، ولكن اللغات الأخرى الوحيدة التي يمكنني أن أفكر في أي يكون الميراث وظائف ثابتة أو يتم تفسير بتكلفة كبيرة في الأداء.

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