سؤال

تحياتي للجميع!

فحص الرمز الخاص بي، وصلت إلى هذا الخط المثير للاهتمام:

const CString &refStr = ( CheckCondition() ) ? _T("foo") : _T("bar");

الآن أنا تماما في حيرة، ولا أستطيع أن أفهم لماذا قانوني. بقدر ما أفهم، يجب تهيئة Conder Refere، إما باستخدام قيمة R أو قيمة L. المراجع غير المهيمية لا يمكن أن توجد. لكن ()؟ يقوم المشغل بتنفيذ وظيفة التحقق () قبل تعيين القيمة المرجعية. أستطيع أن أرى الآن، أنه في حين يتم تنفيذ الاختيار ()، فإن Refstr موجود، ولكن لا يزال غير مهيأ. ماذا سيحدث إذا سيقوم الاختيار () بإلقاء استثناء، أو التحكم في التحكم مع بيان goto؟ هل سيترك الإشارة غير مهيأة أو أنا أفتقد شيئا؟

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

المحلول

مثال أبسط: const int x = foo();

هذا ثابت جدا يجب تهيئة، ولهذا foo() يحتاج إلى أن يسمى. يحدث ذلك بالترتيب اللازم: X يأتي حيز الوجود فقط عند إرجاع Foo.

للإجابة على أسئلتك الإضافية: إذا foo() سيكون throw, ، سيتم القبض على الاستثناء من قبل catch() مكان ما. ال try{} كتلة لذلك catch() محاط const int x = foo(); بشكل ملحوظ. لذلك const int x هو خارج النطاق بالفعل، وهذا غير ذي صلة بأنه لم يحصل أبدا على قيمة. وإذا لم يكن هناك catch للاستثناء، البرنامج الخاص بك (بما في ذلك const int x) ذهب.

C ++ ليس لديه عشوائي goto'س. يمكنهم القفز في الداخل foo() ولكن هذا لا يهم؛ foo() لا يزال يتعين على العودة.

نصائح أخرى

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

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

المراجع غير المهيمية لا يمكن أن توجد.

لسوء الحظ، يمكن القيام بأشياء مضحكة أثناء التهيئة. هل يمكن أن تكون مكتوبة أيضا

const int& a = foobar(a) ? 1 : 2;

أو لهذه المسألة

const int& a = a;

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

"comeautest.c"، الخط 9: تحذير: يتم استخدام متغير "A" قبل تعيين قيمته

  const int& a = foobar(a) ? 1 : 2;
                        ^

بطبيعة الحال، يمكن أن يؤدي ذلك فقط إلى سلوك غير محدد كما هو الحال مع استخدام أي متغير غير مهم.

مثالك على ما يرام، لأنك لا تستخدم المرجع قبل تهيئة.

أستطيع أن أرى الآن، أنه في حين يتم تنفيذ الاختيار ()، فإن Refstr موجود، ولكن لا يزال غير مهيأ.

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

إذا كان التعليمات البرمجية داخل التهيئة يؤدي إلى حالة خطأ، refStr لن توجد موجودة، ولن يكون موجودا من أي وقت مضى.

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

سيجلب لك استثناء إلى مكان حيث لا يمكن الوصول إلى المراجع ولا يمكنك الذهاب إلى مكان من هناك. لن يتمكن Goto من الخروج من الفيك () إذا كانت وظيفة، ولن تتمكن من استخدام GOTO إذا كان ماكرو. سيكون ل LongJMP () نفس التأثير كاستثناء: ستذهب إلى مكان حيث لا يمكن الوصول إلى المراجع.

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