سؤال

لدي بعض الأسئلة حول إرجاع مرجع إلى متغير محلي من وظيفة:

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

أسئلتي هي =>

  1. هو تنفيذ getA1() صيح؟ أشعر أنه غير صحيح لأنه يعود عنوان متغير محلي أو مؤقت.

  2. أي من العبارات في main (1،2،3) سيؤدي إلى سلوك غير محدد؟

  3. في const A& newA1 = getA1(); هل الضمان القياسي لن يتم تدمير ملزمة مؤقتة من مرجع كونستاني حتى يخرج المرجع من النطاق؟

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

المحلول

1. هو getA1() التنفيذ الصحيح؟ أشعر أنه غير صحيح لأنه يعود عنوان المتغير المحلي أو مؤقت.

الإصدار الوحيد من getAx() هذا صحيح في البرنامج الخاص بك هو getA3(). وبعد لدى كل من الآخرين سلوك غير محدد بغض النظر عن كيفية استخدامك لاحقا.

2. أي من العبارات في الرئيسية (1،2،3) سيؤدي إلى سلوك غير محدد؟

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

3. في const A& newA1 = getA1(); هل الضمانات القياسية التي ملزمة مؤقتة من قبل const لن يتم تدمير المرجع حتى يخرج المرجع من النطاق؟

لا. ما يلي هو مثال على ذلك:

A const & newConstA3 = getA3 ();

هنا، getA3() إرجاع مؤقت ومدى هذا المؤقت هو الآن ملزم للكائن newConstA3. وبعد وبعبارة أخرى سوف توجد مؤقتة حتى newConstA3 يخرج النطاق.

نصائح أخرى

Q1: نعم، هذه مشكلة، انظر الإجابة على Q2.

Q2: 1 و 2 غير محدد لأنها تشير إلى المتغيرات المحلية على كومة GETAA1 و GETA2. تخرج هذه المتغيرات من النطاق ولم تعد متوفرة ويمكن الكتابة فوق الأسوأ لأن المكدس تتغير باستمرار. Works GetA3 منذ إنشاء نسخة من قيمة الإرجاع وإرجاعها إلى المتصل.

Q3: لا يوجد مثل هذا الضمان لرؤية الإجابة على Q2.

أعتقد أن المشكلة الرئيسية هي أنك لا تعود مؤقتا على الإطلاق، يجب عليك

return A(5);

بدلا من

A a(5);
return a;

وإلا فإنك تعود عنوان متغير محلي، وليس مؤقتا. والوقت المؤقت للإشارة فقط يعمل فقط للوقود.

أعتقد أنه شرح هنا:مؤقت لاشجع

إذا كنت ترغب في ترجمة هذا على VC6، فستحصل على هذا التحذير

تحذير برنامج التحويل البرمجي ****** (المستوى 1) C4172 عنوان إرجاع المتغير المحلي أو المؤقتة وظيفة إرجاع عنوان المتغير المحلي أو كائن مؤقت. يتم تدمير المتغيرات المحلية والكائنات المؤقتة عند إرجاع الوظيفة، وبالتالي فإن العنوان الذي تم إرجاعه غير صالح. ******

أثناء الاختبار لهذه المشكلة، وجدت شيئا مثيرا للاهتمام (رمز معين يعمل في VC6):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

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