سؤال

لقد قرأت إجابات على أسئلة مقابلة C ++ من بينها واحد يعززني:

س: متى يتم إنشاء المتغيرات المؤقتة بواسطة برنامج التحويل البرمجي C ++؟

ج: شريطة أن تكون معلمة الوظيفة هي "مرجع const" ، يقوم برنامج التحويل البرمجي بإنشاء متغير مؤقت في متابعة طريقتين.

أ) الوسيطة الفعلية هي النوع الصحيح ، لكنها ليست lvalue

double Cube(const double & num)
{
  num = num * num * num;
  return num;
}

double temp = 2.0;
double value = cube(3.0 + temp); // argument is a expression and not a Lvalue

ب) الوسيطة الفعلية من النوع الخطأ ، ولكن من نوع يمكن تحويله إلى النوع الصحيح

 long temp = 3L;
 double value = cuberoot(temp); // long to double conversion

سؤالي هو بمجرد أن تكون وسيطة الوظيفة أ مرجع const, ، لماذا يولد المترجم المتغير المؤقت ، أليس هذا التناقض الذاتي؟ أيضا ، هل يجب أن يفشل مكعب الوظيفة في التجميع لأنه يعدل وسيطة const؟

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

المحلول

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

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

أنت محق في num = num * num * num; كونها غير صالحة. هذا خطأ في النص ، لكن الوسيطة المقدمة من قبلها.

نصائح أخرى

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

ال Cube الوظيفة مكسورة بالفعل (غير متشكل) لأنها تحاول تعديل أ const القيمة.

تبدو خاطئة بالنسبة لي - وتوليد GCC خطأ:

const_ref.cpp: In function ‘double cube(const double&)’:
const_ref.cpp:3: error: assignment of read-only reference ‘num’

المترجم يستطيع توليد متغير مؤقت. ليس من الضروري أن.

ونعم، Cube لا ينبغي أن تجمع في الواقع.

لأنه في كلا المثالين ، لا يوجد كائن غير مؤقت من النوع الصحيح.

أعتقد أنك محق في فشل مكعب الوظيفة. على أي حال ، يجب أن يفشل ذلك ، ويفعل على المترجم الخاص بي (VC ++ 2008).

أما لإنشاء مؤقت:

سيتم إنشاء قيمة مؤقتة لدعم مرجع const كلما كانت الوسيطة الفعلية:

ط) ليس من النوع الصحيح للمرجع ، و 2) يمكن تحويله ضمنيًا إلى النوع الصحيح.

في المثال أ) من سؤالك ، مؤقت double يتم إنشاؤه للاحتفاظ بالقيمة 3.0 + temp. ثم Cube() يسمى مع أ const الإشارة إلى المؤقتة. هذا لأنه لا يمكن أن يكون لديك إشارة إلى 3.0 + temp نظرًا لأن هذا ليس متغيرًا (إنه rvalue - نتيجة التعبير) وبالتالي لا يحتوي على عنوان ذاكرة ، ولا يمكنه دعم المرجع. ضمنيًا ، سوف يخلق المترجم مؤقتًا double ثم تعيينها قيمة 3.0 + temp.

في مثالك ب) ، لديك ملف long, ، لكن وظيفتك تتطلب أ double. سيتم تحويل المترجم ضمنيًا long إلى double. يفعل هذا عن طريق إنشاء مؤقت double, ، تعيين القيمة المحولة لـ temp, ، ثم إنشاء ملف const الإشارة إلى المؤقتة ، وتمرير تلك الإشارة إلى cuberoot

نعم. يجب أن تفشل Cube () ، كما أظهرت ذلك هنا ، في التجميع.

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