การจัดการข้อยกเว้น C ++

ข้อยกเว้นคือปัญหาที่เกิดขึ้นระหว่างการทำงานของโปรแกรม ข้อยกเว้น C ++ คือการตอบสนองต่อสถานการณ์พิเศษที่เกิดขึ้นในขณะที่โปรแกรมกำลังทำงานเช่นความพยายามที่จะหารด้วยศูนย์

ข้อยกเว้นเป็นวิธีการถ่ายโอนการควบคุมจากส่วนหนึ่งของโปรแกรมไปยังอีกส่วนหนึ่ง การจัดการข้อยกเว้น C ++ สร้างขึ้นจากคำหลักสามคำ:try, catch, และ throw.

  • throw- โปรแกรมจะแสดงข้อยกเว้นเมื่อปัญหาปรากฏขึ้น ทำได้โดยใช้ไฟล์throw คำสำคัญ.

  • catch- โปรแกรมตรวจจับข้อยกเว้นด้วยตัวจัดการข้อยกเว้นที่ตำแหน่งในโปรแกรมที่คุณต้องการจัดการปัญหา catch คีย์เวิร์ดบ่งบอกถึงการจับข้อยกเว้น

  • try - ก tryบล็อกระบุบล็อกของรหัสที่จะเปิดใช้งานข้อยกเว้นเฉพาะ ตามด้วยบล็อกจับอย่างน้อยหนึ่งบล็อก

สมมติว่าบล็อกจะเพิ่มข้อยกเว้นเมธอดจะจับข้อยกเว้นโดยใช้การรวมกันของ try และ catchคำหลัก บล็อก try / catch ถูกวางไว้รอบ ๆ โค้ดที่อาจสร้างข้อยกเว้น รหัสภายในบล็อก try / catch เรียกว่ารหัสป้องกันและไวยากรณ์สำหรับการใช้ try / catch ดังต่อไปนี้ -

try {
   // protected code
} catch( ExceptionName e1 ) {
   // catch block
} catch( ExceptionName e2 ) {
   // catch block
} catch( ExceptionName eN ) {
   // catch block
}

คุณสามารถลงรายการได้หลายรายการ catch เพื่อตรวจจับข้อยกเว้นประเภทต่างๆในกรณีของคุณ try บล็อกมีข้อยกเว้นมากกว่าหนึ่งข้อในสถานการณ์ต่างๆ

การโยนข้อยกเว้น

สามารถโยนข้อยกเว้นที่ใดก็ได้ภายในบล็อกรหัสโดยใช้ throwคำให้การ. ตัวถูกดำเนินการของคำสั่ง throw จะกำหนดประเภทสำหรับข้อยกเว้นและสามารถเป็นนิพจน์ใดก็ได้และประเภทของผลลัพธ์ของนิพจน์จะกำหนดประเภทของข้อยกเว้นที่ถูกโยน

ต่อไปนี้เป็นตัวอย่างของการโยนข้อยกเว้นเมื่อเกิดการหารด้วยเงื่อนไขศูนย์ -

double division(int a, int b) {
   if( b == 0 ) {
      throw "Division by zero condition!";
   }
   return (a/b);
}

การจับข้อยกเว้น

catch บล็อกตาม tryบล็อกจับข้อยกเว้นใด ๆ คุณสามารถระบุประเภทของข้อยกเว้นที่คุณต้องการตรวจจับและสิ่งนี้ถูกกำหนดโดยการประกาศข้อยกเว้นที่ปรากฏในวงเล็บหลังจากที่จับคีย์เวิร์ด

try {
   // protected code
} catch( ExceptionName e ) {
  // code to handle ExceptionName exception
}

โค้ดด้านบนจะมีข้อยกเว้น ExceptionNameชนิด. หากคุณต้องการระบุว่าบล็อกจับควรจัดการกับข้อยกเว้นประเภทใด ๆ ที่ถูกโยนลงในบล็อกลองคุณต้องใส่จุดไข่ปลา ... ระหว่างวงเล็บที่ล้อมรอบการประกาศข้อยกเว้นดังนี้ -

try {
   // protected code
} catch(...) {
  // code to handle any exception
}

ต่อไปนี้เป็นตัวอย่างซึ่งทำให้เกิดการหารด้วยข้อยกเว้นเป็นศูนย์และเราจับมันในบล็อกจับ

#include <iostream>
using namespace std;

double division(int a, int b) {
   if( b == 0 ) {
      throw "Division by zero condition!";
   }
   return (a/b);
}

int main () {
   int x = 50;
   int y = 0;
   double z = 0;
 
   try {
      z = division(x, y);
      cout << z << endl;
   } catch (const char* msg) {
     cerr << msg << endl;
   }

   return 0;
}

เนื่องจากเรากำลังเพิ่มข้อยกเว้นประเภท const char*ดังนั้นในขณะที่จับข้อยกเว้นนี้เราต้องใช้ const char * ใน catch block หากเรารวบรวมและเรียกใช้โค้ดด้านบนสิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -

Division by zero condition!

ข้อยกเว้นมาตรฐาน C ++

C ++ แสดงรายการข้อยกเว้นมาตรฐานที่กำหนดไว้ใน <exception>ซึ่งเราสามารถใช้ในโปรแกรมของเรา สิ่งเหล่านี้จัดอยู่ในลำดับชั้นระดับแม่และลูกที่แสดงด้านล่าง -

นี่คือคำอธิบายเล็ก ๆ ของแต่ละข้อยกเว้นที่กล่าวถึงในลำดับชั้นข้างต้น -

ซีเนียร์ No ข้อยกเว้นและคำอธิบาย
1

std::exception

ข้อยกเว้นและคลาสพาเรนต์ของข้อยกเว้น C ++ มาตรฐานทั้งหมด

2

std::bad_alloc

นี้สามารถโยนโดย new.

3

std::bad_cast

นี้สามารถโยนโดย dynamic_cast.

4

std::bad_exception

นี่เป็นอุปกรณ์ที่มีประโยชน์ในการจัดการข้อยกเว้นที่ไม่คาดคิดในโปรแกรม C ++

5

std::bad_typeid

นี้สามารถโยนโดย typeid.

6

std::logic_error

ข้อยกเว้นที่สามารถตรวจพบได้ในทางทฤษฎีโดยการอ่านรหัส

7

std::domain_error

นี่เป็นข้อยกเว้นที่เกิดขึ้นเมื่อใช้โดเมนที่ไม่ถูกต้องทางคณิตศาสตร์

8

std::invalid_argument

สิ่งนี้เกิดขึ้นเนื่องจากข้อโต้แย้งที่ไม่ถูกต้อง

9

std::length_error

สิ่งนี้จะเกิดขึ้นเมื่อสร้างสตริง std :: ที่ใหญ่เกินไป

10

std::out_of_range

สิ่งนี้สามารถโยนได้ด้วยเมธอด 'at' ตัวอย่างเช่น std :: vector และ std :: bitset <> :: operator [] ()

11

std::runtime_error

ข้อยกเว้นที่ไม่สามารถตรวจพบในทางทฤษฎีโดยการอ่านรหัส

12

std::overflow_error

สิ่งนี้จะเกิดขึ้นหากเกิดการล้นทางคณิตศาสตร์

13

std::range_error

เหตุการณ์นี้เกิดขึ้นเมื่อคุณพยายามจัดเก็บค่าที่อยู่นอกช่วง

14

std::underflow_error

สิ่งนี้จะเกิดขึ้นหากเกิดการล้นเกินทางคณิตศาสตร์

กำหนดข้อยกเว้นใหม่

คุณสามารถกำหนดข้อยกเว้นของคุณเองได้โดยการสืบทอดและการลบล้าง exceptionฟังก์ชันคลาส ต่อไปนี้เป็นตัวอย่างซึ่งแสดงให้เห็นว่าคุณสามารถใช้คลาส std :: except เพื่อใช้ข้อยกเว้นของคุณเองในรูปแบบมาตรฐานได้อย่างไร -

#include <iostream>
#include <exception>
using namespace std;

struct MyException : public exception {
   const char * what () const throw () {
      return "C++ Exception";
   }
};
 
int main() {
   try {
      throw MyException();
   } catch(MyException& e) {
      std::cout << "MyException caught" << std::endl;
      std::cout << e.what() << std::endl;
   } catch(std::exception& e) {
      //Other errors
   }
}

สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -

MyException caught
C++ Exception

ที่นี่ what()เป็นวิธีสาธารณะที่จัดเตรียมโดยคลาสข้อยกเว้นและถูกแทนที่โดยคลาสข้อยกเว้นเด็กทั้งหมด สิ่งนี้ส่งคืนสาเหตุของข้อยกเว้น