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:
นี่คือภาพหน้าจอของรหัส:
Code คำอธิบาย:
- รวมไฟล์ส่วนหัว 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:
นี่คือภาพหน้าจอของรหัส:
Code คำอธิบาย:
- รวมไฟล์ส่วนหัว 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:
นี่คือภาพหน้าจอของรหัส:
Code คำอธิบาย:
- รวมไฟล์ส่วนหัว iostream ไว้ในโปรแกรมของเรา เราจะใช้ฟังก์ชันของมันโดยไม่ได้รับข้อผิดพลาด
- รวมไฟล์ส่วนหัวข้อยกเว้นไว้ในโปรแกรมของเรา เราจะใช้ฟังก์ชันของมันเหมือนกับที่ไม่มีข้อผิดพลาด
- รวมเนมสเปซมาตรฐานในโปรแกรมของเราเพื่อใช้คลาสโดยไม่ต้องเรียกมัน
- สร้างคลาสใหม่ชื่อ newException คลาสนี้สืบทอดคลาสข้อยกเว้นของ C++.
- จุดเริ่มต้นของเนื้อหาในชั้นเรียน
- เขียนทับฟังก์ชันสมาชิกเสมือน what() ที่กำหนดไว้ในไฟล์ส่วนหัวข้อยกเว้น จากนั้นเราจะอธิบายข้อยกเว้นของเราเอง ข้อยกเว้นใหม่
- เริ่มต้นคำจำกัดความของข้อยกเว้นใหม่
- ข้อความที่จะถูกส่งกลับหากตรวจพบข้อยกเว้นใหม่
- สิ้นสุดคำจำกัดความของข้อยกเว้นใหม่
- จุดสิ้นสุดของเนื้อหาคลาส newException newex คือชื่อที่จะใช้เพื่อตรวจจับข้อยกเว้นใหม่ของเรา หลังจากนั้น newException จะถูกเรียก
- เรียกใช้ฟังก์ชัน main() ควรเพิ่มตรรกะของโปรแกรมภายในเนื้อหา { ถือเป็นจุดเริ่มต้นของเนื้อหา
- ใช้คำสั่ง try เพื่อทำเครื่องหมายโค้ดที่เราต้องทำเครื่องหมายข้อยกเว้น { ทำเครื่องหมายจุดเริ่มต้นของเนื้อหา try/catch block รหัสที่ล้อมรอบด้วยสิ่งนี้จะได้รับการป้องกัน
- โยนข้อยกเว้น newex หากตรวจพบ
- สิ้นสุดการลองร่างกาย
- ใช้คำสั่ง catch เพื่อตรวจจับข้อยกเว้น ข้อความแสดงข้อผิดพลาดข้อยกเว้นจะถูกเก็บไว้ในตัวแปรเช่น
- พิมพ์ข้อความแสดงข้อผิดพลาดข้อยกเว้นบนคอนโซล
- ส่วนท้ายของคำสั่ง catch
- โปรแกรมควรส่งคืนค่าหากดำเนินการได้สำเร็จ
- ส่วนท้ายของฟังก์ชัน main()
สรุป
- โดยมีข้อยกเว้นในการจัดการใน C++คุณสามารถจัดการกับข้อผิดพลาดรันไทม์ได้
- ข้อผิดพลาดรันไทม์คือข้อผิดพลาดที่เกิดขึ้นระหว่างการทำงานของโปรแกรม
- การจัดการข้อยกเว้นช่วยให้คุณจัดการกับสถานการณ์ที่ไม่คาดคิดในโปรแกรมของคุณ
- เมื่อเกิดเหตุการณ์ที่ไม่คาดคิด การควบคุมโปรแกรมจะถูกถ่ายโอนไปยังตัวจัดการ
- หากต้องการตรวจจับข้อยกเว้น คุณวางส่วนของโค้ดไว้ใต้บล็อก try-catch
- คีย์เวิร์ด `throw` ช่วยให้โปรแกรมโยนข้อยกเว้นได้ping โปรแกรมสำหรับแก้ไขปัญหา
- คำสำคัญ try ช่วยระบุบล็อคโค้ดที่จะเปิดใช้งานข้อยกเว้นบางประการ
- เราสามารถเขียนทับฟังก์ชัน what() ของไฟล์ส่วนหัวข้อยกเว้นเพื่อกำหนดข้อยกเว้นของเราได้




