C++ معالجة الاستثناءات: حاول، التقط، ارمي مثال
⚡ ملخص ذكي
معالجة الاستثناء في C++ تُمكّن هذه الخاصية البرنامج من اكتشاف أخطاء وقت التشغيل والاستجابة لها باستخدام try وcatch وthrow، مما يمنع تعطل البرنامج. ستتعلم هنا الكلمات المفتاحية، والصيغة، والاستثناءات القياسية، والاستثناءات المُعرّفة من قِبل المستخدم مع أمثلة توضيحية.
ما هو التعامل مع الاستثناءات في C++?
معالجة الاستثناء في C++ يوفر لك طريقة للتعامل مع الظروف غير المتوقعة مثل أخطاء وقت التشغيل. ولذلك كلما حدثت ظروف غير متوقعة، يتم نقل التحكم في البرنامج إلى وظائف خاصة تعرف باسم المعالجات.
للتعرف على الاستثناءات، عليك وضع قسم من التعليمات البرمجية تحت فحص الاستثناءات. يتم وضع قسم التعليمات البرمجية داخل كتلة محاولة الالتقاط.
إذا حدث موقف استثنائي داخل هذا القسم من التعليمات البرمجية، فسيتم طرح استثناء. بعد ذلك، سيتولى معالج الاستثناء التحكم في البرنامج.
في حالة عدم حدوث أي ظروف استثنائية، سيتم تنفيذ التعليمات البرمجية بشكل طبيعي. سيتم تجاهل المعالجات.
في هذا C++ البرنامج التعليمي، سوف تتعلم:
لماذا التعامل مع الاستثناءات؟
إليك سبب استخدام معالجة الاستثناءات C++:
- سوف تقوم بفصل كود معالجة الأخطاء الخاص بك عن الكود العادي. وسوف يكون الكود أكثر قابلية للقراءة وأسهل في الصيانة.
- يمكن للوظائف التعامل مع الاستثناءات التي تختارها. حتى لو طرحت الدالة العديد من الاستثناءات، فإنها ستتعامل مع بعضها فقط. سيتعامل المتصل مع الاستثناءات التي لم يتم اكتشافها.
معالجة الاستثناءات للكلمات الرئيسية
معالجة الاستثناء في C++ تدور حول هذه الكلمات الرئيسية الثلاث:
- رمي- عندما يواجه برنامج مشكلة ما، فإنه يطرح استثناء. تساعد الكلمة الأساسية throw البرنامج على تنفيذ الرمي.
- قبض- يستخدم البرنامج معالج الاستثناء للقبض على الاستثناء. تتم إضافته إلى قسم البرنامج حيث تحتاج إلى معالجة المشكلة. يتم ذلك باستخدام الكلمة الأساسية الجذابة.
- محاولة- تحدد كتلة المحاولة كتلة التعليمات البرمجية التي سيتم تنشيط استثناءات معينة لها. يجب أن يتبعه كتلة التقاط واحدة/أكثر.
لنفترض أن كتلة التعليمات البرمجية ستثير استثناءً. سيتم اكتشاف الاستثناء من خلال إحدى الطرق التي تستخدم الكلمات الرئيسية المحاولة والالتقاط. يجب أن تحيط كتلة المحاولة/الالتقاط بالتعليمات البرمجية التي قد تؤدي إلى استثناء. يُعرف هذا الرمز بالرمز المحمي.
بناء الجملة
تأخذ المحاولة/الالتقاط بناء الجملة هذا:
try { // the protected code } catch( Exception_Name exception1 ) { // catch block } catch( Exception_Name exception2 ) { // catch block } catch( Exception_Name exceptionN ) { // catch block }
- على الرغم من أن لدينا عبارة محاولة واحدة، إلا أنه يمكن أن يكون لدينا العديد من عبارات الالتقاط.
- اسم الاستثناء هو اسم الاستثناء الذي سيتم اكتشافه.
- الاستثناء 1 والاستثناء 2 والاستثناء N هي الأسماء المحددة للإشارة إلى الاستثناءات.
مثال 1:
#include<iostream> #include<vector> using namespace std; int main() { vector<int> vec; vec.push_back(0); vec.push_back(1); // access the third element, which doesn't exist try { vec.at(2); } catch (exception& ex) { cout << "Exception occurred!" << endl; } return 0; }
الإخراج:
فيما يلي لقطة شاشة للكود:
Code التفسير:
- قم بتضمين ملف رأس iostream في البرنامج لاستخدامه وظائف.
- قم بتضمين ملف رأس المتجه في البرنامج لاستخدام وظائفه.
- قم بتضمين مساحة الاسم std في البرنامج إلى فئاته دون استدعائها.
- استدعاء الدالة الرئيسية (). يجب إضافة منطق البرنامج داخل جسمه.
- قم بإنشاء متجه باسم vec لتخزين البيانات الصحيحة.
- أضف العنصر 0 إلى المتجه المسمى vec.
- أضف العنصر 1 إلى المتجه المسمى vec.
- تعليق. سيتم تخطيه بواسطة C++ مترجم.
- استخدم عبارة المحاولة للقبض على استثناء. يمثل { بداية نص كتلة المحاولة/الالتقاط. سيصبح الرمز المضاف داخل النص هو الرمز المحمي.
- حاول الوصول إلى العنصر المخزن في الفهرس 2 (العنصر الثالث) للناقل المسمى vec. هذا العنصر غير موجود.
- نهاية نص كتلة المحاولة/الالتقاط.
- قبض على الاستثناء. سيتم تخزين رسالة الخطأ التي تم إرجاعها في المتغير ex.
- اطبع بعض الرسائل على وحدة التحكم إذا تم اكتشاف الاستثناء.
- نهاية جسم كتلة الصيد.
- يجب أن يقوم البرنامج بإرجاع قيمة عند التنفيذ الناجح.
- نهاية نص الوظيفة الرئيسية ().
مثال 2:
#include <iostream> using namespace std; double zeroDivision(int x, int y) { if (y == 0) { throw "Division by Zero!"; } return (x / y); } int main() { int a = 11; int b = 0; double c = 0; try { c = zeroDivision(a, b); cout << c << endl; } catch (const char* message) { cerr << message << endl; } return 0; }
الإخراج:
فيما يلي لقطة شاشة للكود:
Code التفسير:
- قم بتضمين ملف رأس iostream في البرنامج لاستخدام وظائفه.
- قم بتضمين مساحة الاسم std في البرنامج إلى فئاته دون استدعائها.
- قم بإنشاء دالة باسم zeroDivision تأخذ وسيطتين صحيحتين، x وy. يجب أن تعيد الدالة نتيجة مزدوجة.
- استخدم عبارة if للتحقق مما إذا كانت قيمة وسيطة المتغير y هي 0. يمثل { بداية نص if.
- الرسالة التي سيتم إرجاعها/رميها إذا كانت y تساوي 0.
- نهاية نص عبارة if.
- يجب أن تقوم الدالة ZeroDivision بإرجاع قيمة x/y.
- نهاية نص الدالة ZeroDivision.
- استدعاء الطريقة الرئيسية (). يمثل { بداية هذه الطريقة.
- قم بتعريف متغير صحيح وتخصيص القيمة 11 له.
- قم بتعريف متغير عدد صحيح b وتخصيص القيمة 0 له.
- إعلان متغير مزدوج c وتعيين القيمة 0 له.
- استخدم عبارة المحاولة للقبض على استثناء. يمثل { بداية نص كتلة المحاولة/الالتقاط. سيصبح الرمز المضاف داخل النص هو الرمز المحمي.
- قم باستدعاء دالة zeroDivision وتمريرها إلى الوسيطتين a وb، أي 11 و0. سيتم تخزين نتيجة هذه العملية في المتغير c.
- اطبع قيمة المتغير c على وحدة التحكم.
- نهاية نص كتلة المحاولة/الالتقاط.
- قبض على الاستثناء. سيتم تخزين رسالة الخطأ التي تم إرجاعها في الرسالة المتغيرة.
- قم بطباعة رسالة الخطأ التي تم إرجاعها على وحدة التحكم.
- نهاية جسم كتلة الصيد.
- يجب أن يقوم البرنامج بإرجاع قيمة عند التنفيذ الناجح.
- نهاية نص الوظيفة الرئيسية ().
C++ الاستثناءات القياسية
C++ يأتي مع قائمة الاستثناءات القياسية المحددة في فصل. هذه موصوفة أدناه:
| استثناء | الوصف |
|---|---|
| الأمراض المنقولة جنسيا::استثناء | هذا استثناء والفئة الأم لجميع المعايير C++ استثناءات. |
| الأمراض المنقولة جنسيا::bad_alloc | يتم طرح هذا الاستثناء بواسطة كلمة رئيسية جديدة. |
| الأمراض المنقولة جنسيا::bad_cast | هذا استثناء تم طرحه بواسطةdynamic_cast. |
| الأمراض المنقولة جنسيا::bad_exception | جهاز مفيد للتعامل مع الاستثناءات غير المتوقعة في C++ البرامج. |
| الأمراض المنقولة جنسيا::bad_typeid | استثناء تم طرحه بواسطة typeid. |
| الأمراض المنقولة جنسيا::logic_error | يمكن اكتشاف هذا الاستثناء نظريًا من خلال قراءة التعليمات البرمجية. |
| الأمراض المنقولة جنسيا::domain_error | هذا استثناء تم طرحه بعد استخدام مجال غير صالح رياضيًا. |
| الأمراض المنقولة جنسيا::invalid_argument | تم طرح استثناء لاستخدام وسيطات غير صالحة. |
| الأمراض المنقولة جنسيا :: length_error | تم طرح استثناء بعد إنشاء سلسلة كبيرة::string. |
| الأمراض المنقولة جنسيا::out_of_range | ألقيت في الأسلوب. |
| الأمراض المنقولة جنسيا::runtime_error | هذا استثناء لا يمكن اكتشافه من خلال قراءة الكود. |
| الأمراض المنقولة جنسيا::overflow_error | يتم طرح هذا الاستثناء بعد حدوث تجاوز رياضي. |
| الأمراض المنقولة جنسيا::range_error | يتم طرح هذا الاستثناء عند محاولة تخزين قيمة خارج النطاق. |
| الأمراض المنقولة جنسيا::underflow_error | تم طرح استثناء بعد حدوث التجاوز الرياضي. |
الاستثناءات المحددة من قبل المستخدم
استخدم C++ تسمح لنا فئة std::exception بتعريف الكائنات التي يمكن طرحها كاستثناءات. وقد تم تعريف هذه الفئة في header. يزودنا الفصل بوظيفة عضو افتراضي تسمى ماذا.
تقوم هذه الدالة بإرجاع تسلسل أحرف منتهية بقيمة خالية من النوع char *. يمكننا الكتابة فوقه في الفئات المشتقة للحصول على وصف الاستثناء.
على سبيل المثال:
#include <iostream> #include <exception> using namespace std; class newException : public exception { virtual const char* what() const throw() { return "newException occurred"; } } newex; int main() { try { throw newex; } catch (exception& ex) { cout << ex.what() << '\n'; } return 0; }
الإخراج:
فيما يلي لقطة شاشة للكود:
Code التفسير:
- قم بتضمين ملف رأس iostream في برنامجنا. سوف نستخدم وظائفه دون الحصول على أخطاء.
- قم بتضمين ملف رأس الاستثناء في برنامجنا. سوف نستخدم وظائفها مثل ما دون أخطاء.
- قم بتضمين مساحة الاسم std في برنامجنا لاستخدام فئاتها دون استدعائها.
- قم بإنشاء فئة جديدة باسم newException. ترث هذه الفئة فئة الاستثناء C++.
- بداية الجسم الطبقي.
- قم بالكتابة فوق وظيفة العضو الظاهري () المحددة في ملف رأس الاستثناء. سنقوم بعد ذلك بوصف الاستثناء الخاص بنا، الاستثناء الجديد.
- ابدأ بتعريف الاستثناء الجديد.
- الرسالة التي سيتم إرجاعها إذا تم اكتشاف الاستثناء الجديد.
- انتهى تعريف الاستثناء الجديد.
- نهاية نص الفئة newException. newex هو الاسم الذي سيتم استخدامه لالتقاط الاستثناء الجديد، وبعده سيتم استدعاء newException.
- استدعاء الدالة الرئيسية (). يجب إضافة منطق البرنامج داخل جسمه. يمثل { بداية جسمه.
- استخدم عبارة محاولة لوضع علامة على الكود الذي نحتاج إلى وضع علامة الاستثناء فيه. يمثل { بداية نص كتلة المحاولة/الالتقاط. سيصبح الكود المحاط بهذا محميًا.
- قم برمي استثناء newex إذا تم اكتشافه.
- نهاية نص المحاولة.
- استخدم عبارة الصيد للقبض على الاستثناء. سيتم تخزين رسالة خطأ الاستثناء في المتغير ex.
- اطبع رسالة خطأ الاستثناء على وحدة التحكم.
- نهاية نص بيان الصيد.
- يجب أن يُرجع البرنامج قيمة إذا تم تنفيذه بنجاح.
- نهاية نص الدالة main().





