C++ การจัดการข้อยกเว้น: ลอง จับ โยน ตัวอย่าง
การจัดการข้อยกเว้นคืออะไร C++?
การจัดการข้อยกเว้นใน C++ มอบวิธีจัดการกับสถานการณ์ที่ไม่คาดคิด เช่น ข้อผิดพลาดรันไทม์ ดังนั้นเมื่อใดก็ตามที่เกิดเหตุการณ์ที่ไม่คาดคิด การควบคุมโปรแกรมจะถูกถ่ายโอนไปยังฟังก์ชันพิเศษที่เรียกว่าตัวจัดการ
ในการตรวจจับข้อยกเว้น คุณจะต้องวางโค้ดบางส่วนไว้ภายใต้การตรวจสอบข้อยกเว้น ส่วนของโค้ดถูกวางไว้ภายในบล็อก try-catch
หากสถานการณ์พิเศษเกิดขึ้นภายในส่วนของโค้ดนั้น ข้อยกเว้นจะถูกส่งออกไป ถัดไป ตัวจัดการข้อยกเว้นจะเข้าควบคุมโปรแกรม
ในกรณีที่ไม่มีเหตุการณ์พิเศษเกิดขึ้น รหัสจะทำงานตามปกติ ตัวจัดการจะถูกละเว้น
ในการนี้ C++ กวดวิชาคุณจะได้เรียนรู้:
เหตุใดจึงต้องมีการจัดการข้อยกเว้น
นี่คือเหตุผลในการใช้ Exception Handling in C++:
- คุณจะแยกโค้ดการจัดการข้อผิดพลาดออกจากโค้ดปกติ โค้ดจะอ่านง่ายขึ้นและดูแลรักษาง่ายขึ้น
- ฟังก์ชันต่างๆ สามารถจัดการกับข้อยกเว้นที่เลือกได้ แม้ว่าฟังก์ชันจะมีข้อยกเว้นมากมาย แต่จะจัดการได้เพียงบางส่วนเท่านั้น ผู้โทรจะจัดการกับข้อยกเว้นที่ไม่ถูกตรวจจับ
คำหลักการจัดการข้อยกเว้น
การจัดการข้อยกเว้นใน C++ หมุนรอบคำสำคัญสามคำนี้:
- โยน– เมื่อโปรแกรมประสบปัญหา โปรแกรมจะแสดงข้อยกเว้น คีย์เวิร์ด Throw ช่วยให้โปรแกรมทำการโยน
- จับ– โปรแกรมใช้ตัวจัดการข้อยกเว้นเพื่อตรวจจับข้อยกเว้น มันถูกเพิ่มเข้าไปในส่วนของโปรแกรมที่คุณต้องการจัดการปัญหา เสร็จสิ้นโดยใช้คีย์เวิร์ด catch
- ลอง– try block ระบุบล็อกโค้ดที่จะเปิดใช้งานข้อยกเว้นบางประการ ควรตามด้วยบล็อก catch หนึ่ง/หลายบล็อก
สมมติว่าบล็อกโค้ดจะทำให้เกิดข้อยกเว้น ข้อยกเว้นจะถูกตรวจจับโดยวิธีการที่ใช้คีย์เวิร์ด try and catch บล็อก try/catch ควรล้อมรอบโค้ดที่อาจทำให้เกิดข้อยกเว้น รหัสดังกล่าวเรียกว่ารหัสที่ได้รับการป้องกัน
วากยสัมพันธ์
try/catch ใช้ไวยากรณ์นี้:
try { // the protected code } catch( Exception_Name exception1 ) { // catch block } catch( Exception_Name exception2 ) { // catch block } catch( Exception_Name exceptionN ) { // catch block }
- แม้ว่าเราจะมีคำสั่ง try หนึ่งคำสั่ง แต่เราก็สามารถมีคำสั่ง catch ได้หลายคำสั่ง
- ExceptionName คือชื่อของข้อยกเว้นที่จะตรวจจับ
- ข้อยกเว้น 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; }
Output:
นี่คือภาพหน้าจอของรหัส:
คำอธิบายรหัส:
- รวมไฟล์ส่วนหัว iostream ไว้ในโปรแกรมเพื่อใช้งาน ฟังก์ชั่น.
- รวมไฟล์ส่วนหัวเวกเตอร์ไว้ในโปรแกรมเพื่อใช้ฟังก์ชันต่างๆ
- รวมเนมสเปซมาตรฐานในโปรแกรมเข้ากับคลาสโดยไม่ต้องเรียกมัน
- เรียกใช้ฟังก์ชัน main() ควรเพิ่มตรรกะของโปรแกรมภายในเนื้อหา
- สร้างเวกเตอร์ชื่อ vec เพื่อเก็บข้อมูลจำนวนเต็ม
- เพิ่มองค์ประกอบ 0 ให้กับเวกเตอร์ชื่อ vec
- เพิ่มองค์ประกอบ 1 ให้กับเวกเตอร์ชื่อ vec
- ความคิดเห็น. มันจะถูกข้ามโดย C++ ผู้รวบรวม.
- ใช้คำสั่ง try เพื่อตรวจจับข้อยกเว้น { ทำเครื่องหมายจุดเริ่มต้นของเนื้อหา try/catch block รหัสที่เพิ่มภายในเนื้อหาจะกลายเป็นรหัสที่ได้รับการป้องกัน
- ลองเข้าถึงองค์ประกอบที่เก็บไว้ที่ดัชนี 2 (องค์ประกอบที่สาม) ของเวกเตอร์ชื่อ vec ไม่มีองค์ประกอบนี้
- จุดสิ้นสุดของเนื้อหาบล็อก try/catch
- จับข้อยกเว้น ข้อความแสดงข้อผิดพลาดที่ส่งคืนจะถูกเก็บไว้ในตัวแปรเช่น
- พิมพ์ข้อความบนคอนโซลหากตรวจพบข้อยกเว้น
- ส่วนท้ายของตัวบล็อกจับ
- โปรแกรมควรคืนค่าเมื่อดำเนินการสำเร็จ
- จุดสิ้นสุดของเนื้อหาฟังก์ชัน main()
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; }
Output:
นี่คือภาพหน้าจอของรหัส:
คำอธิบายรหัส:
- รวมไฟล์ส่วนหัว iostream ไว้ในโปรแกรมเพื่อใช้ฟังก์ชันต่างๆ
- รวมเนมสเปซมาตรฐานในโปรแกรมเข้ากับคลาสโดยไม่ต้องเรียกมัน
- สร้างฟังก์ชันชื่อ zeroDivision ที่รับอาร์กิวเมนต์จำนวนเต็มสองตัวคือ x และ y ฟังก์ชันควรส่งคืนผลลัพธ์เป็น double
- ใช้คำสั่ง if เพื่อตรวจสอบว่าค่าของอาร์กิวเมนต์ตัวแปร y เป็น 0 หรือไม่ { ทำเครื่องหมายจุดเริ่มต้นของ if body
- ข้อความที่จะถูกส่งกลับ/โยนถ้า y เป็น 0
- ส่วนท้ายของคำสั่ง if
- ฟังก์ชัน zeroDivision ควรส่งคืนค่า x/y
- จุดสิ้นสุดของเนื้อความของฟังก์ชัน zeroDivision
- เรียกเมธอด main() { ถือเป็นจุดเริ่มต้นของเมธอดนี้
- ประกาศตัวแปรจำนวนเต็มและกำหนดค่าให้เป็น 11
- ประกาศตัวแปรจำนวนเต็ม b และกำหนดค่าให้เป็น 0
- ประกาศตัวแปรสองตัว c และกำหนดค่าเป็น 0
- ใช้คำสั่ง try เพื่อตรวจจับข้อยกเว้น { ทำเครื่องหมายจุดเริ่มต้นของเนื้อหา try/catch block รหัสที่เพิ่มภายในเนื้อหาจะกลายเป็นรหัสที่ได้รับการป้องกัน
- เรียกใช้ฟังก์ชัน zeroDivision และส่งผ่านอาร์กิวเมนต์ a และ b นั่นคือ 11 และ 0 ผลลัพธ์ของการดำเนินการนี้จะถูกเก็บไว้ในตัวแปร c
- พิมพ์ค่าของตัวแปร c บนคอนโซล
- จุดสิ้นสุดของเนื้อหาบล็อก try/catch
- จับข้อยกเว้น ข้อความแสดงข้อผิดพลาดที่ส่งคืนจะถูกจัดเก็บไว้ในข้อความตัวแปร
- พิมพ์ข้อความแสดงข้อผิดพลาดที่ส่งคืนบนคอนโซล
- ส่วนท้ายของตัวบล็อกจับ
- โปรแกรมควรคืนค่าเมื่อดำเนินการสำเร็จ
- จุดสิ้นสุดของเนื้อหาฟังก์ชัน main()
C++ ข้อยกเว้นมาตรฐาน
C++ มาพร้อมกับรายการข้อยกเว้นมาตรฐานที่กำหนดไว้ใน ระดับ. สิ่งเหล่านี้อธิบายไว้ด้านล่าง:
ข้อยกเว้น | Descriptไอออน |
---|---|
มาตรฐาน::ข้อยกเว้น | นี่เป็นข้อยกเว้นและเป็นคลาสหลักของมาตรฐานทั้งหมด C++ ข้อยกเว้น |
มาตรฐาน::bad_alloc | ข้อยกเว้นนี้เกิดขึ้นโดยคำสำคัญใหม่ |
มาตรฐาน::bad_cast | นี่เป็นข้อยกเว้นที่เกิดขึ้นโดย dynamic_cast |
มาตรฐาน::bad_Exception | อุปกรณ์ที่มีประโยชน์สำหรับการจัดการข้อยกเว้นที่ไม่คาดคิดใน C++ โปรแกรม |
มาตรฐาน::bad_typeid | มีข้อยกเว้นเกิดขึ้นโดย typeid |
มาตรฐาน::logic_error | ข้อยกเว้นนี้สามารถตรวจพบได้ในทางทฤษฎีโดยการอ่านโค้ด |
มาตรฐาน::domain_error | นี่เป็นข้อยกเว้นที่เกิดขึ้นหลังจากใช้โดเมนที่ไม่ถูกต้องทางคณิตศาสตร์ |
มาตรฐาน::invalid_argument | มีข้อยกเว้นสำหรับการใช้อาร์กิวเมนต์ที่ไม่ถูกต้อง |
มาตรฐาน::length_error | เกิดข้อยกเว้นหลังจากสร้าง std::string ขนาดใหญ่ |
มาตรฐาน::อยู่นอกช่วง_ | โยนโดยวิธีการ |
มาตรฐาน::runtime_error | นี่เป็นข้อยกเว้นที่ไม่สามารถตรวจพบได้โดยการอ่านโค้ด |
มาตรฐาน::overflow_error | ข้อยกเว้นนี้เกิดขึ้นหลังจากการโอเวอร์โฟลว์ทางคณิตศาสตร์เกิดขึ้น |
มาตรฐาน::range_error | ข้อยกเว้นนี้จะเกิดขึ้นเมื่อคุณพยายามจัดเก็บค่าที่อยู่นอกช่วง |
มาตรฐาน::underflow_error | ข้อยกเว้นที่เกิดขึ้นหลังจากเกิดอันเดอร์โฟลว์ทางคณิตศาสตร์ |
ข้อยกเว้นที่ผู้ใช้กำหนด
เหตุการณ์ C++ คลาส std::Exception ช่วยให้เราสามารถกำหนดวัตถุที่สามารถส่งเป็นข้อยกเว้นได้ คลาสนี้ถูกกำหนดไว้ใน ส่วนหัว คลาสจัดเตรียมฟังก์ชันสมาชิกเสมือนชื่ออะไรให้กับเรา
ฟังก์ชันนี้ส่งคืนลำดับอักขระที่สิ้นสุดด้วยค่า null ประเภท 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; }
Output:
นี่คือภาพหน้าจอของรหัส:
คำอธิบายรหัส:
- รวมไฟล์ส่วนหัว iostream ไว้ในโปรแกรมของเรา เราจะใช้ฟังก์ชันของมันโดยไม่ได้รับข้อผิดพลาด
- รวมไฟล์ส่วนหัวข้อยกเว้นไว้ในโปรแกรมของเรา เราจะใช้ฟังก์ชันของมันเหมือนกับที่ไม่มีข้อผิดพลาด
- รวมเนมสเปซมาตรฐานในโปรแกรมของเราเพื่อใช้คลาสโดยไม่ต้องเรียกมัน
- สร้างคลาสใหม่ชื่อ newException คลาสนี้สืบทอดคลาสข้อยกเว้นของ C++.
- จุดเริ่มต้นของเนื้อหาในชั้นเรียน
- เขียนทับฟังก์ชันสมาชิกเสมือน what() ที่กำหนดไว้ในไฟล์ส่วนหัวข้อยกเว้น จากนั้นเราจะอธิบายข้อยกเว้นของเราเอง ข้อยกเว้นใหม่
- เริ่มต้นคำจำกัดความของข้อยกเว้นใหม่
- ข้อความที่จะถูกส่งกลับหากตรวจพบข้อยกเว้นใหม่
- สิ้นสุดคำจำกัดความของข้อยกเว้นใหม่
- จุดสิ้นสุดของเนื้อหาคลาส newException newex คือชื่อที่จะใช้เพื่อตรวจจับข้อยกเว้นใหม่ของเรา หลังจากนั้น newException จะถูกเรียก
- เรียกใช้ฟังก์ชัน main() ควรเพิ่มตรรกะของโปรแกรมภายในเนื้อหา { ถือเป็นจุดเริ่มต้นของเนื้อหา
- ใช้คำสั่ง try เพื่อทำเครื่องหมายโค้ดที่เราต้องทำเครื่องหมายข้อยกเว้น { ทำเครื่องหมายจุดเริ่มต้นของเนื้อหา try/catch block รหัสที่ล้อมรอบด้วยสิ่งนี้จะได้รับการป้องกัน
- โยนข้อยกเว้น newex หากตรวจพบ
- สิ้นสุดการลองร่างกาย
- ใช้คำสั่ง catch เพื่อตรวจจับข้อยกเว้น ข้อความแสดงข้อผิดพลาดข้อยกเว้นจะถูกเก็บไว้ในตัวแปรเช่น
- พิมพ์ข้อความแสดงข้อผิดพลาดข้อยกเว้นบนคอนโซล
- ส่วนท้ายของคำสั่ง catch
- โปรแกรมควรส่งคืนค่าหากดำเนินการได้สำเร็จ
- ส่วนท้ายของฟังก์ชัน main()
สรุป
- โดยมีข้อยกเว้นในการจัดการใน C++คุณสามารถจัดการกับข้อผิดพลาดรันไทม์ได้
- ข้อผิดพลาดรันไทม์คือข้อผิดพลาดที่เกิดขึ้นระหว่างการทำงานของโปรแกรม
- การจัดการข้อยกเว้นช่วยให้คุณจัดการกับสถานการณ์ที่ไม่คาดคิดในโปรแกรมของคุณ
- เมื่อเกิดเหตุการณ์ที่ไม่คาดคิด การควบคุมโปรแกรมจะถูกถ่ายโอนไปยังตัวจัดการ
- หากต้องการตรวจจับข้อยกเว้น คุณวางส่วนของโค้ดไว้ใต้บล็อก try-catch
- คีย์เวิร์ด Throw ช่วยให้โปรแกรมส่งข้อยกเว้น ช่วยให้โปรแกรมจัดการกับปัญหาได้
- คำสำคัญ try ช่วยระบุบล็อคโค้ดที่จะเปิดใช้งานข้อยกเว้นบางประการ
- เราสามารถเขียนทับฟังก์ชัน what() ของไฟล์ส่วนหัวข้อยกเว้นเพื่อกำหนดข้อยกเว้นของเราได้