سؤال

عند استخدام متغيرات ثابتة في C++, أنا غالبا ما ينتهي يريد تهيئة متغير واحد يمر أخرى إلى المنشئ.وبعبارة أخرى, أريد إنشاء ثابتة الحالات التي تعتمد على بعضها البعض.

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

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

أحد الاحتمالات هو خدعة مع وظيفة ثابتة الأعضاء:

Type& globalObject()
{
    static Type theOneAndOnlyInstance;
    return theOneAndOnlyInstance;
}

والواقع أن هذا العمل.للأسف عليك أن تكتب globalObject().MemberFunction () ، بدلا من globalObject.MemberFunction () ، مما أدى إلى مربكة إلى حد ما وغير أنيق رمز العميل.

تحديث: شكرا على ردود الفعل الخاصة بك.ومن المؤسف أنه في الواقع يبدو أنني قد أجبت عن سؤالي.أعتقد أنني يجب أن نتعلم كيف نتعايش معها...

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

المحلول

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

قراءة C++ التعليمات البنود بدءا من https://isocpp.org/wiki/faq/ctors#static-init-order

نصائح أخرى

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

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

والواقع أن هذا العمل.للأسف عليك أن تكتب globalObject().MemberFunction () ، بدلا من globalObject.MemberFunction () ، مما أدى إلى مربكة إلى حد ما وغير أنيق رمز العميل.

ولكن الشيء الأكثر أهمية هو أنه يعمل وأنه هو عدم دليل ، أي.فإنه ليس من السهل تجاوز الاستخدام الصحيح.

برنامج صحة ينبغي أن تكون الأولوية الأولى الخاص بك.أيضا, IMHO ، () أعلاه هو محض الأسلوبية - أي.غير مهم تماما.

اعتمادا على النظام الأساسي الخاص بك, كن حذرا من الكثير من الديناميكية التهيئة.هناك كمية صغيرة نسبيا من التنظيف التي يمكن أن تحدث الحيوية المهيآت (انظر هنا).يمكنك حل هذه المشكلة باستخدام كائن العالمي الحاويات التي تحتوي على أعضاء مختلفة العالمية الكائنات.ولذلك عليك:

Globals & getGlobals ()
{
  static Globals cache;
  return cache;
}

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

getGlobals().configuration.memberFunction ();

إذا كنت تريد حقا هل يمكن أن ننهي هذا في ماكرو لإنقاذ القليل من الكتابة باستخدام ماكرو:

#define GLOBAL(X) getGlobals().#X
GLOBAL(object).memberFunction ();

على الرغم من أن هذا هو مجرد النحوية السكر الأولي الخاص بك حل.

معظم المجمعين (رابط) فعلا الدعم (غير محمول) طريقة تحديد النظام.على سبيل المثال, مع visual studio يمكنك استخدام init_seg pragma لترتيب التهيئة إلى عدة مجموعات مختلفة.AFAIK لا توجد وسيلة لضمان النظام داخل كل مجموعة.لأن هذا هو غير المحمولة قد ترغب في النظر إذا كان يمكنك إصلاح التصميم الخاص بك لا تتطلب ذلك ، ولكن الخيار هو هناك.

dispite سن هذا الموضوع, وأود أن أقترح الحل وجدت.كما أشار من قبل لي ، C++ لا توفر أي آلية ثابتة التهيئة الطلب.ما أقترحه هو أن encapsule كل عضو ثابت داخل أسلوب ثابت من الفئة التي بدورها تهيئة الأعضاء وتوفير الوصول في وجوه المنحى الموضة.اسمحوا لي أن أقدم لكم مثالا ، لنفترض أننا نريد أن نحدد الطبقة اسمه "الرياضيات" والذي كان من بين الأعضاء الآخرين, يحتوي على "بي":

class Math {
public:
   static const float Pi() {
       static const float s_PI = 3.14f;
       return s_PI;
   }
}

s_PI سيتم تهيئة المرة الأولى Pi() استدعاء أسلوب (في دول مجلس التعاون الخليجي).تكون على علم:المحلية الكائنات مع ساكنة تخزين التنفيذ تعتمد lifecyle, لمزيد من التفاصيل تحقق في 6.7.4 2.

ثابت الكلمة, C++ القياسية

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

// File scope static pointer is thread safe and is initialized first.
static Type * theOneAndOnlyInstance = 0;

Type& globalObject()
{
    if(theOneAndOnlyInstance == 0)
    {
         // Put mutex lock here for thread safety
         theOneAndOnlyInstance = new Type();
    }

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