إذا الطبقات مع وظائف افتراضية يتم تنفيذها مع vtables كيف هي فئة مع عدم وجود وظائف افتراضية تنفيذها ؟

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

  •  01-07-2019
  •  | 
  •  

سؤال

على وجه الخصوص, لا يجب أن تكون هناك نوع من وظيفة المؤشر في المكان على أية حال ؟

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

المحلول

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

struct A 
{
  void foo ();
  void bar () const;
};

هو أساسا نفس:

struct A 
{
};

void foo (A * this);
void bar (A const * this);

على vtable هناك حاجة إلى ذلك أن نسميه حق وظيفة لدينا كائن معين على سبيل المثال.على سبيل المثال, إذا كان لدينا:

struct A 
{
  virtual void foo ();
};

تنفيذ 'فو' قد التقريبية إلى شيء من هذا القبيل:

void foo (A * this) {
  void (*realFoo)(A *) = lookupVtable (this->vtable, "foo");
  (realFoo)(this);   // Make the call to the most derived version of 'foo'
}

نصائح أخرى

أعتقد أن عبارة "الطبقات مع وظائف افتراضية يتم تنفيذها مع vtables"مضلل لك.

عبارة يجعل الأمر يبدو مثل الطبقات مع وظائف افتراضية يتم تنفيذها "في الطريق"و الطبقات دون وظائف افتراضية يتم تنفيذها "في الطريقة ب".

في الواقع, فصول افتراضية وظائف ، بالإضافة إلى يجري تنفيذها في الطبقات ، لديهم أيضا vtable.طريقة أخرى لمعرفة ذلك هو أن "'vtables' تنفيذ 'الظاهري وظيفة' جزء من فئة".

المزيد من التفاصيل عن كيفية العمل على حد سواء:

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

أعضاء البيانات

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

طرق

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

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

void CMyThingy::DoSomething(int arg);
{
    // do something
}

مترجم حقا هل هذا:

void CMyThingy_DoSomething(CMyThingy* this, int arg)
{
    /do something
}

وأخيرا ، عندما كنت أكتب هذا:

myObj.doSomething(aValue);

المترجم يقول:

CMyThingy_DoSomething(&myObj, aValue);

لا حاجة مؤشرات الدالة في أي مكان!المترجم يعرف بالفعل الطريقة التي كنت تدعو لذلك المكالمات مباشرة.

أساليب ثابتة بل هي أبسط.ليس لديهم هذا مؤشر, لذلك فهي تنفذ تماما كما كنت تكتب لهم.

هذا هو!والباقي هو مجرد مريحة جملة تحلية:المترجم يعرف أي فئة أسلوب ينتمي إلى ، حتى يجعل متأكد من أنها لا تمكنك من استدعاء الدالة من دون تحديد أي واحد.كما يستخدم تلك المعرفة يترجم myItem إلى this->myItem عندما لا لبس فيها إلى القيام بذلك.

(نعم هذا صحيح:عضو في الأسلوب دائما القيام به بشكل غير مباشر عن طريق المؤشر ، حتى لو كنت لا ترى واحدة)

(تحرير:إزالة الجملة الأخيرة و نشرها بشكل منفصل بحيث يمكن انتقد بشكل منفصل)

الظاهري الأساليب مطلوبة عندما تريد استخدام تعدد الأشكال.على virtual التعديل يضع الأسلوب في VMT على الربط المتأخر ثم في وقت تقرر الطريقة التي من الفئة التي يتم تنفيذها.

إذا كان الأسلوب هو وليس الظاهري - هو قرر في وقت الترجمة من أي فئة سبيل المثال سوف يتم تنفيذها.

مؤشرات الدالة تستخدم في الغالب رد.

إذا فئة مع وظيفة افتراضية يتم تنفيذها مع vtable ، ثم فئة مع أي وظيفة افتراضية يتم تنفيذها دون vtable.

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

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

(سحبت هذا القسم من بلدي الأصلي الإجابة بحيث يمكن انتقد بشكل منفصل.هو الكثير أكثر إيجازا إلى نقطة سؤالك حتى في طريقة انها أفضل بكثير الإجابة)

لا توجد مؤشرات الدالة;بدلا من ذلك, مترجم يتحول المشكلة من الداخل إلى الخارج.

مترجم المكالمات وظيفة العالمية مع مؤشر إلى كائن بدلا من استدعاء بعض وأشار إلى وظيفة داخل الكائن

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

هناك حاجة إلى مؤشرات الدالة كما أنه غير قادر على تغيير أثناء وقت التشغيل.

الفروع التي تم إنشاؤها مباشرة في التعليمات البرمجية المترجمة عن الأساليب ؛ تماما مثل إذا كان لديك المهام التي ليست في الطبقة في جميع فروع يتم إنشاؤها مباشرة لهم.

مترجم/رابط روابط مباشرة الأساليب التي سيتم تنفيذها.لا حاجة vtable المراوغة.راجع للشغل, ما علاقة هذا مع "كومة مقابلكومة"?

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