سؤال

إذا كان لدي فصل يسمى اختبار ::

class Test
{
    static std::vector<int> staticVector;
};

متى staticVector يتم بناؤه ومتى يتم تدميره؟

هل هو مع إنشاء مثيل للكائن الأول من فئة الاختبار، أو تماما مثل المتغيرات الثابتة العادية؟

فقط للتوضيح، جاء هذا السؤال إلى ذهني بعد قراءة مفاهيم لغات البرمجة (Sebesta Ch-5.4.3.1) وهو يقول::

لاحظ أنه عندما ثابتة يظهر المعدل في إعلان متغير في تعريف الفئة في C ++ و Java و C#، لا علاقة له مع عمر المتغير.في هذا السياق ، يعني أن المتغير هو متغير فئة ، بدلاً من متغير مثيل.يمكن أن يكون الاستخدام المتعدد للكلمة المحجوزة مربكًا بشكل خاص لأولئك الذين يتعلمون اللغة.

هل فهمت؟:(

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

المحلول

تمامًا مثل المتغيرات الثابتة (العالمية) العادية.

نصائح أخرى

أريد أن أكتب بعض النصوص حول التهيئة أيضًا، والتي يمكنني الارتباط بها لاحقًا.


أولا قائمة الاحتمالات.

  • مساحة الاسم ثابتة
  • فصل ثابتة
  • محلي ثابتة

مساحة الاسم ثابتة

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

أمثلة:

يطبع البرنامج التالي A(1) A(2)

struct A { 
  A(int n) { std::printf(" A(%d) ", n); } 
};

A a(1);
A b(2);

وما يلي، على أساس نفس الفئة، يطبع A(2) A(1)

extern A a;
A b(2);
A a(1);

لنفترض أن هناك وحدة ترجمة حيث msg يتم تعريفه على النحو التالي

char const *msg = "abc";

ثم المطبوعات التالية abc.لاحظ أن p يتلقى التهيئة الديناميكية.ولكن لأن التهيئة الثابتة (char const* هو نوع POD، و "abc" هو عنوان تعبير ثابت) من msg يحدث قبل ذلك، وهذا أمر جيد، و msg ويضمن أن تتم تهيئته بشكل صحيح.

extern const char *msg;
struct P { P() { std::printf("%s", msg); } };
P p;
  • متحرك ليس من الضروري أن تتم تهيئة الكائن قبل الرئيسي بأي ثمن.يجب أن تتم التهيئة قبل الاستخدام الأول لكائن أو وظيفة وحدة الترجمة الخاصة بها.هذا مهم للمكتبات الديناميكية القابلة للتحميل.

فئة ثابتة

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

ساكنة محلية

  • بالنسبة للإحصائيات المحلية، هناك قواعد خاصة.
  • تتم تهيئة كائنات نوع POD التي تمت تهيئتها بتعبير ثابت قبل إدخال الكتلة الخاصة بها التي تم تعريفها فيها.
  • تتم تهيئة الكائنات الثابتة المحلية الأخرى في المرة الأولى التي يمر فيها التحكم عبر تعريفها.لا تعتبر التهيئة مكتملة عند طرح استثناء.ستتم محاولة التهيئة مرة أخرى في المرة القادمة.

مثال:يطبع البرنامج التالي 0 1:

struct C { 
  C(int n) { 
    if(n == 0)
      throw n;
    this->n = n;
  }
  int n;
};

int f(int n) {
  static C c(n);
  return c.n;
}

int main() {
  try { 
    f(0); 
  } catch(int n) { 
    std::cout << n << " "; 
  }
  f(1); // initializes successfully
  std::cout << f(2);  
}

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

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

يتم إنشاؤه في نفس الوقت الذي يتم فيه إنشاء المتغيرات العالمية وتدميرها جنبًا إلى جنب مع المتغيرات العالمية أيضًا.

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

يحدث التدمير عندما يتم تدمير المتغيرات العالمية.

يتم تدمير المتغيرات العامة بالترتيب العكسي الذي تم إنشاؤه فيه؛بعد الخروج من الوظيفة الرئيسية

يعتبر،
أوفانيس

ملاحظة.:أقترح إلقاء نظرة على C++-Standard، الذي يشرح (يحدد) كيف ومتى يتم إنشاء أو تدمير متغيرات الأعضاء العامة أو الثابتة.

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

std::vector اختبار::staticVector;
أو
std::vector Test::staticVector=std::vector(/* ctor params here */);

بعض معلومات VC++ المحددة في حال كان هذا هو ما تستخدمه:

  1. يحدث إنشاء متغيرات الفئة الثابتة في نفس الوقت الذي يتم فيه إنشاء متغيرات ثابتة/عالمية أخرى.
  2. في نظام التشغيل Windows، تكون وظيفة بدء تشغيل CRT مسؤولة عن هذا البناء.هذه هي نقطة الدخول الفعلية لمعظم البرامج التي تقوم بتجميعها (وهي الوظيفة التي تستدعي وظيفة Main/Winmain الخاصة بك).بالإضافة إلى ذلك، فهو مسؤول عن تهيئة دعم وقت تشغيل C بالكامل (على سبيل المثال، تحتاج إليه لاستخدام malloc).
  3. ترتيب الإنشاء غير محدد، ولكن عند استخدام برنامج التحويل البرمجي Microsoft VC، سيكون ترتيب الإنشاء للأنواع الأساسية موافقًا، على سبيل المثال، تكون الكتابة قانونية وآمنة

احصائيات.ح:...إعلان ماي كلاس...ثابت ثابت كثافةت أ ؛ثابت كثافة العمليات ب؛ثابت int ar[];} statics.cpp:

const int MyClass::a = 2;
int MyClass::b = a+3;
int MyClass::ar[a] = {1,2}

يعني متغير عضو الفئة الثابتة أنه على الرغم من وجود كائنات متعددة من نفس الفئة، فإن المتغير سيكون هو نفسه بالنسبة لجميع كائنات الفئة.

لذا، أود أن أقول إنه يتم إنشاؤه عند إنشاء مثيل للكائن الأول ويتم تدميره عندما يتم تدمير الكائن الأخير.

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