c++ - يوزر - ما هي قواعد استدعاء منشئ superclass؟




معنى كلمة يوزر بالعربي (6)

ما هي قواعد C ++ لاستدعاء منشئ superclass من فئة فرعية واحدة؟

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


إذا كان لديك معلمات افتراضية في منشئ الأساس الخاص بك ، فسيتم استدعاء الفئة الأساسية تلقائيًا.

using namespace std;

class Base
{
    public:
    Base(int a=1) : _a(a) {}

    protected:
    int _a;
};

class Derived : public Base
{
  public:
  Derived() {}

  void printit() { cout << _a << endl; }
};

int main()
{
   Derived d;
   d.printit();
   return 0;
}

الانتاج هو: 1


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

إذا كنت تريد استدعاء مُنشئ أساسي مع الوسيطات ، فعليك كتابة ذلك بوضوح في المُنشئ المشتق كما يلي:

class base
{
  public:
  base (int arg)
  {
  }
};

class derived : public base
{
  public:
  derived () : base (number)
  {
  }
};

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


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


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

class Sub : public Base
{
  Sub(int x, int y)
  : Base(x), member(y)
  {
  }
  Type member;
};

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

class Sub : public Base
{
  Sub(int x, int y)
  try : Base(x), member(y)
  {
    // function body goes here
  } catch(const ExceptionType &e) {
    throw kaboom();
  }
  Type member;
};

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


لا أحد ذكر تسلسل استدعاءات منشئ عندما يستمد فئة من فئات متعددة. التسلسل كما هو مذكور في حين تستمد الطبقات.


يتم استدعاء منشئات الفئة الأساسية تلقائيًا إذا لم يكن لديهم وسيطة. إذا كنت تريد استدعاء منشئ superclass مع وسيطة ، يجب عليك استخدام قائمة التهيئة منشئ فئة فرعية. بخلاف Java ، يدعم C ++ تواريث متعددة (للأفضل أو الأسوأ) ، لذلك يجب الإشارة إلى الفئة الأساسية بالاسم بدلاً من "super ()".

class SuperClass
{
    public:

        SuperClass(int foo)
        {
            // do something with foo
        }
};

class SubClass : public SuperClass
{
    public:

        SubClass(int foo, int bar)
        : SuperClass(foo)    // Call the superclass constructor in the subclass' initialization list.
        {
            // do something with bar
        }
};

مزيد من المعلومات حول قائمة التهيئة في المنشور here here .





constructor