سؤال

خذ بعين الاعتبار نموذج التعليمات البرمجية التالي أدناه:

#include <iostream>

using namespace std;

class base
{
   public:
      base()
      {
         cout << "ctor in base class\n";
      }
};

class derived1 : public base
{
   public:
      derived1()
      {
         cout <<"ctor in derived class\n";
      }
};

int main()
{
   derived1 d1obj;
   return 0;
}

أسئلة

  1. متى d1obj تم إنشاؤه، يتم استدعاء المنشئين بترتيب الاشتقاق:يتم استدعاء مُنشئ الفئة الأساسية أولاً ثم مُنشئ الفئة المشتقة.هل يتم ذلك للسبب التالي: In-order to construct the derived class object the base class object needs to be constructed first?

  2. يفعل d1obj يحتوي على كائن من الدرجة الأساسية؟

أقوم بإضافة سؤال آخر

3) عند إنشاء d1obj، يصل التحكم أولاً إلى مُنشئ الفئة الأساسية ثم ينتقل إلى مُنشئ الفئة المشتقة؟أو هل هو حول الطريق الأخر :يصل أولاً إلى مُنشئ الفئة المشتقة، ويجد أنه يحتوي على فئة أساسية وبالتالي ينتقل التحكم إلى المُنشئ في الفئة الأساسية؟

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

المحلول

1) نعم ، القواعد هي التي شيدت أولا ثم غير ثابت أعضاء البيانات ، ثم منشئ فئة مشتقة يسمى.والسبب في ذلك أن القانون في منشئ هذه الفئة يمكن أن نرى استخدام بالكامل شيدت قاعدة.

2) نعم.يمكنك أن تأخذ هذا تماما حرفيا:داخل الذاكرة المخصصة إلى فئة مشتقة كائن هناك منطقة تسمى "قاعدة الطبقة الفرعية كائن".فئة مشتقة كائن "يحتوي على" قاعدة الطبقة subobject في بالضبط بنفس الطريقة التي يحتوي الأعضاء subobjects أي غير ثابت أعضاء البيانات.في الواقع على الرغم من المثال المذكور في السؤال يحدث أن تكون حالة خاصة:"فارغة قاعدة الطبقة الأمثل".هذه قاعدة الطبقة subobject يجوز أن يكون حجم صفر ، على الرغم كاملة كائنات من نوع base هي لم الحجم صفر.

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

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

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

المترجم دائما "يعرف" ما قواعد الصف ، لأنه يمكنك فقط إنشاء كائن من نوع كاملة ، مما يعني المترجم يمكن أن نرى تعريف الفئة ، التي تحدد القواعد.لذلك ليس هناك سؤال فقط "وجدت أن لديها قاعدة الطبقة" عندما منشئ هو دخل - مترجم يعرف أن لديها قاعدة الطبقة ، وإذا كان استدعاء منشئ الفئة الأساسية يقع داخل فئة مشتقة منشئ التعليمات البرمجية هذا فقط من أجل راحة مترجم.ذلك يمكن أن تنبعث منها يدعو إلى قاعدة فئة الصانعين في كل مكان يمكنك إنشاء كائن ، وفي هذا الشأن في الحالات التي تستمد منشئ فئة يمكن أن يكون هو inlined هذا التأثير النهائي.

نصائح أخرى

  1. نعم.تخيل أنه في مُنشئ الفئة المشتقة، تريد استخدام بعض أعضاء الفئة الأساسية.ولذلك، فإنها تحتاج إلى التهيئة.لذلك فمن المنطقي أن يتم استدعاء مُنشئ الفئة الأساسية أولاً.

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

نعم، ونعم.


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

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

1-- نعم.وهو منطقي بهذه الطريقة.

كائنات النوع المشتق 1 هي كائنات خاصة من قاعدة النوع، مما يعني أنه، كأول شيء، فهي كائنات من قاعدة النوع.هذا هو ما تم إنشاؤه أولا، ثم "المشتق 1" يضيف "التخصص" إلى الكائن.

2-- أنها ليست مسألة تحتوي على، فهي ميراث.انظر الفقرة أعلاه لفهم هذه الإجابة بشكل أفضل.

  1. نعم

  2. حسنًا، من الناحية النظرية، ليس حقًا. d1obj يحتوي على كافة أعضاء البيانات التي يوجد مثيل لها base سوف، ويستجيب لجميع وظائف الأعضاء التي سيفعلها المثيل المذكور، ولكنه لا "يحتوي" على مثيل لـ base:لا يمكنك أن تقول d1obj.base.func() على سبيل المثال.على سبيل المثال، إذا قمت بتحميل طريقة أعلن عنها والدك بشكل زائد، فيمكنك الاتصال بها d1obj.base::func() للحصول على تنفيذه، بدلاً من مجرد الاتصال d1obj->func().

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

class derived2 /*no parent listed */ {
public:

   derived2() :_b() {}

private:
    base _b;
}

يتيح لك هذا البناء الاستفادة من الأساليب التي تم تنفيذها بالفعل بواسطة base, ، كتفاصيل تنفيذ الطرق الخاصة بك، دون الحاجة إلى الكشف عن أي أساليب base تم الإعلان عنه للعامة ولكنك لا ترغب في منح حق الوصول إليه.مثال مهم على ذلك هو stack, ، والتي يمكن أن تحتوي على مثيل لحاوية STL أخرى (مثل vector, deque أو list)، ثم استخدمها back() لتنفيذ top(), push_back() ل push() و pop_back() ل pop(), كل ذلك دون الحاجة إلى كشف الطرق الأصلية للمستخدم.

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