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