ماذا يحدث عندما نرمي كائنًا/متغيرًا لنلتقطه؟

StackOverflow https://stackoverflow.com/questions/9399467

  •  29-10-2019
  •  | 
  •  

سؤال

سؤالان 1) ماذا يحدث عندما يتم طرح كائن/متغير للقبض عليه؟قل على سبيل المثال،

int foo() {
   FILE *fp = ....;
   int dummy = 10;
   int *dummy_ptr = new int[10];
   throw 1;
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

في هذه الحالة ماذا يحدث هنا؟تم إنشاء متغير جديد ثم تم تمريره؟؟؟

ماذا لو استخدمت مؤشرًا أو متغيرًا بدون مرجع

مثل catch (int *i) // أو catch (int i)

أيضًا، هل تم تحرير/إغلاق جميع المتغيرات/الموارد المعلنة أو التي تم بدئها داخل النطاق؟

2) أيضًا في حالة Rethrow ، إذا كنت أخطط لإعادة الإشارة إلى مرجع ، فإن الصيد الثاني يحصل على متغير جديد ، إذا كنت أعيد تشغيله بدون مرجع (أي) بالقيمة ، فإن التغييرات التي تم إجراؤها في الرمية الوسيطة لا تتأثر ....

int goo() {
    throw 2;
}

int foo() {
   try{
      goo();
   } catch(int &i) { // (or) catch(int i) // i is not changing in the next line.
      i = 2;
      throw;
   }
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

انتاج:catch (int & i) // prints 2 catch (int i) // prints 1

من حكمي،

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

(على سبيل المثال) تدفق التحكم للمتغير لا يرمي في الواقع المصيد الوسيط .....

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

المحلول

نعم ، عندما يتم طرح استثناء ، تكون جميع المتغيرات التلقائية دمرت ، في نطاق الرمي وجميع النطاقات المرفقة حتى تم الوصول إلى المعالج.

ملاحظة واحدة على هذا ، لن يتم إلغاء تخصيص ذاكرتك في رمز الترقيم العام ، ولن يتم إغلاق الرمز العام لمؤشر الرمز العام.

نصائح أخرى

في هذه الحالة ماذا يحدث هنا؟متغير جديد تم إنشاؤه ثم تمريره؟

نعم؛عندما ترمي كائنًا، يتم إنشاؤه في مكان ما، ثم يتم تدميره بمجرد معالجة الاستثناء (أي بعد مغادرة catch منع دون إعادة الرمي).

ماذا لو استخدمت مؤشرًا أو متغيرًا بدون مرجع؟وفي حالة الإعادة أيضاً..

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

أيضًا، هل تم إغلاق جميع المتغيرات المعلنة أو التي بدأت داخل النطاق؟

عندما يتم طرح استثناء، يتم تدمير كافة المتغيرات التلقائية، في نطاق throw وجميع النطاقات المرفقة حتى يتم الوصول إلى المعالج.المتغيرات المخصصة ديناميكيًا (مثل ملف new int[10]) نكون لا وظائف التنظيف المحذوفة والتعسفية مثل fclose بالتأكيد لا يتم استدعاؤها FILE* المتغيرات، ما لم تتم إدارتها بواسطة كائن قائم على النطاق مثل المؤشر الذكي.

لا أعتقد أنه يمكنك تسميته متغيرًا؛ليس لها اسم.لكن كائن جديد من النوع int يتم إنشاؤه ، في مكان غير محدد يحدده التنفيذ.عند التقاطها بالرجوع إليها ، يرتبط المرجع بهذا الكائن المخفي.وعندما تسقط من نهاية كتلة الصيد ، أو تترك كتلة الصيد بأي وسيلة غير إعادة الاستثناء نفسه ، يتم "تحرير" الكائن.

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