سؤال

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

void foo() 
{ 
    static string plonk = "When will I die?";
}
هل كانت مفيدة؟

المحلول

عمر وظيفة static المتغيرات تبدأ المرة الأولى[0] البرنامج تدفق لقاءات الإعلان وينتهي في برنامج إنهاء الخدمة.وهذا يعني أن وقت التشغيل يجب تنفيذ بعض الكتاب حفظ من أجل التدمير ذلك إلا إذا كان فعلا بناؤها.

بالإضافة إلى ذلك, حيث يقول أن المتلفات من الأجسام الساكنة يجب تشغيل في ترتيب عكسي من الانتهاء من البناء[1], و من أجل البناء قد تعتمد على برنامج محدد المدى ، من أجل البناء يجب أن تؤخذ بعين الاعتبار.

على سبيل المثال

struct emitter {
    string str;
    emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
    ~emitter() { cout << "Destroyed " << str << endl; }
};

void foo(bool skip_first) 
{
    if (!skip_first)
        static emitter a("in if");
    static emitter b("in foo");
}

int main(int argc, char*[])
{
    foo(argc != 2);
    if (argc == 3)
        foo(false);
}

الإخراج:

ج:>sample.exe
التي تم إنشاؤها في فو
دمرت في فو

ج:>sample.exe 1
التي تم إنشاؤها في إذا
التي تم إنشاؤها في فو
دمرت في فو
دمرت في إذا

ج:>sample.exe 1 2
التي تم إنشاؤها في فو
التي تم إنشاؤها في إذا
دمرت في إذا
دمرت في فو

[0] منذ C++98[2] لا إشارة إلى مواضيع متعددة كيف سيتم التصرف في مجتمع متعدد الخيوط بيئة غير محدد و يمكن أن يكون مشكلة كما رودي ويذكر.

[1] C++98 القسم 3.6.3.1 [الأساسي.تبدأ.الأجل]

[2] في C++11 احصائيات يتم تهيئة في موضوع طريقة آمنة, هذا هو المعروف أيضا باسم سحر السكون.

نصائح أخرى

وموتي هو الصحيح عن هذا الامر، ولكن هناك بعض الأشياء الأخرى للنظر:

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

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

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

وليس التفسيرات الموجودة كاملة حقا بدون سيادة الفعلية من هذا المعيار، وجدت في 6.7:

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

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

وFWIW، Codegear C ++ باني لا التدمير في الترتيب المتوقع وفقا لهذا المعيار.

C:\> sample.exe 1 2
Created in foo
Created in if
Destroyed in foo
Destroyed in if

... وهو سبب آخر لعدم الاعتماد على ترتيب الدمار!

على متغيرات ثابتة هي تأتي في اللعب مرة واحدة تنفيذ البرنامج يبدأ وأنها لا تزال متاحة حتى تنفيذ البرنامج ينتهي.

ثابت المتغيرات التي تم إنشاؤها في شريحة بيانات من الذاكرة.

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