Exceptions
ในการเขียนโปรแกรม อาจจะมีบางครั้งที่โปรแกรมเกิดข้อผิดพลาดขึ้น ซึ่งข้อผิดพลาดนี้อาจจะเกิดจากการเขียนโปรแกรมหรืออาจจะเกิดจากสภาพแว้ดล้อมอย่างอื่น เมื่อเกิดข้อผิดพลาดนี้ขึ้นจะทำให้การเขียนโปรแกรมหยุดทำงาน ดังนั้นในภาษา C++ เราสามารถแก้ไขปัญหานี้ได้โดยการใช้ Exception สำหรับควบคุมและจัดการกับข้อผิดพลาดที่เกิดขึ้น ในบทนี้ เราจะพูดเกี่ยวกับการใช้งาน Exception ในภาษา C++
C++ exceptions
Exceptions เป็นวิธีที่จะจัดการกับโปรแกรมเพื่อให้ไปทำอย่างอื่นเมื่อมีข้อผิดพลาดเกิดขึ้น โปรแกรมจะพยายามทำบางอย่างที่เราได้ระบุไว้ ถ้ามีข้อผิดพลาดเกิดขึ้น โปรแกรมจะย้ายไปทำงานอีกส่วนของโปรแกรมที่เรียกว่าฟังก์ชันตัวจัดการ Exceptions มีรูปแบบดังนี้:
try
{
// statetments
}
catch (exceoption e1)
{
// exception handler 1
}
catch (exceoption e2)
{
// exception handler 2
}
...
ถ้าเราไม่ใช้ Exception ในโปรแกรมของเรา มันอาจจะเผชิญกับข้อผิดพลาด เช่น Running time errors หรือ Memory allocation errors มี 3 คำสั่งเกี่ยวกับ Exception คือ
thrown
, try
และ catch
โดยในบล็อคของคำสั่ง try
จะเป็นคำสั่งสำหรับตรวจสอบข้อผิดพลาดขึ้นและถ้าหากเกิดข้อผิดพลาดขึ้น โปรแกรมจะทำการโยน Exception ออกไปยังบล็อคของคำสั่ง catch
และในบล็อคของคำสั่ง catch
จะต้องมีการตรวจจับ Exception ที่เกิดขึ้น หรือเราสามารถใช้คำสั่ง throw
เพื่อโยน Exception ออกไปได้
ต่อไปมาดูตัวอย่างในการจัดการกับ Exception โดยเราจะกำหนดให้โปรแกรมของเรานั้นเกิด Exception ขึ้นเมื่อตัวเลขมีค่าเป็น 0
#include <iostream>
using namespace std;
int main()
{
int n = 0;
try
{
if (n == 0)
throw n;
else
cout << "n is not zero." << endl;
}
catch (int e)
{
cout << "An exception occurred: n = " << e << endl;
}
return 0;
}
ในตัวอย่าง โปรแกรมนั้นมีการจัดการกับข้อผิดพลาด ในบล็อคคำสั่งของ
try
โปรแกรมของเราจะตรวจสอบว่า n
เป็น 0 เราจะใช้คำสั่ง throw
ซึ่งมี n
อาร์กิวเมนต์ที่จะส่งต่อไปยังบล็อคคำสั่งของ catch
(Handlers function) ประเภทของพารามิเตอร์จะต้องตรงกัน ในตัวอย่างนี้ เราได้ส่ง n
ซึ่งเป็นข้อมูบแบบ int
ฟังก์ชัน catch
จะต้องมีพารามิเตอร์เป็นแบบ int e
ด้วยเช่นกันAn exception occurred: n = 0
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งจะทำให้เกิด Exception ขึ้นเพราะตัวเลขในตัวแปร
n
นั้นมีค่าเป็น 0 โปรแกรมนี้แสดงให้คุณเห็นว่าเราสามารถทำให้เกิด Exception ได้ด้วยคำสั่ง throw
ฟังก์ชัน
catch
สามารถเป็นฟังก์ชันแบบ Overloaded ได้โดยการที่มันมีประเภทของพารามิเตอร์ที่แตกต่างกัน คอมไพลเลอร์จะทำการตัดสินใจว่าจะส่งไปที่ฟังก์ชันไหนเมื่อโปรแกรมทำงาน Overloaded handlers ได้สร้างขึ้นในรูปแบบเหมือนข้างบน นี่เป็นตัวอย่างtry
{
throw 10.0;
}
catch (int e1)
{
// catch integer exception
}
catch (float e2)
{
// catch floating point exception
}
catch (string e2)
{
// catch string exception
}
...
ต่อไปมาดูตัวอย่างในการตรวจจับ Exception แบบ Overloaded catch block โดยโปรแกรมของเราจะเป็นโปรแกรมในการดูข้อมูลในอาเรย์ที่รับค่า Index ของอาเรย์ผ่านทางคีย์บอร์ด นี่เป็นตัวอย่างของโปรแกรม
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name[] = {"Mateo", "Danny", "Thomas", "John"};
int i;
try
{
cout << "Enter an array index (0 - 3): ";
cin >> i;
if (i < 0)
{
throw i;
}
if (i >= 4)
{
string err_msg = "Array index out of bound.";
throw err_msg;
}
cout << name[i] << endl;
}
catch (int n)
{
cout << "Exception: negative number (" << n << ")." << endl;
}
catch (string n)
{
cout << "Exception: " << n << endl;
}
return 0;
}
ในตัวอย่าง เราได้ประกาศ String อาเรย์สำหรับเก็บชื่อจำนวน 4 ชื่อ โดยโปรแกรมของเราจะรับค่า Index ของอาเรย์เข้ามาและทำการตรวจสอบ Index นั้นว่าถูกต้องหรือไม่ในบล็อคของคำสั่ง
try
if (i < 0)
{
throw i;
}
การตรวจสอบครั้งแรกเป็นการตรวจสอบว่า Index ของอาเรย์นั้นน้อยกว่า 0 หรือไม่ ถ้าหากใช้ เราทำการโยน Integer exception และส่งตัวเลขดังกล่าวออกไป ในบล็อคของคำสั่ง
catch
เราได้ทำการตรวจจับสำหรับ Integer exceptionif (i >= 4)
{
string err_msg = "Array index out of bound.";
throw err_msg;
}
ต่อมาเราได้ทำการตรวจสอบ Index อีกครั้ง ในตอนนี้เราทำการตรวจสอบถ้าหาก Index นั้นมีขนาดมากกว่า Index ของสมาชิกตัวสุดท้ายของอาเรย์ซึ่งเป็นค่าที่ไม่ถูกต้อง เราทำให้เกิด String exception โดยการส่งข้อความผิดพลาดออกไป และในบล็อคคำสั่ง
catch
เราได้ตรวจจับสำหรับ Exception นี้Enter an array index (0 - 3): -1
Exception: negative number (-1).
Enter an array index (0 - 3): 5
Exception: Array index out of bound.
Enter an array index (0 - 3): 1
Danny
นี่เป็นผลลัพธ์จากการรันโปรแกรมทั้งสามครั้ง และเราได้กรอก Index เป็น -1 5 และ 1 ตามลำดับ จะเห็นว่าในครั้งแรกนั้นเกิด Exception ขึ้นเพราะว่า Index นั้นเป็นจำนวนเต็มลบ ครั้งที่สองก็เกิดเช่นกันเพราะ Index ที่กรอกเข้ามานั้นมีขนาดใหญ่กว่าอาเรย์ และสุดท้ายเป็นค่าของ Index ที่ถูกต้องและโปรแกรมแสดงชื่อของ Index ดังกล่าว
Standard exceptions
ในภาษา C++ มีไลบรารี่ของ Exceptions มาตรฐานสำหรับการใช้งาน ซึ่งมันจะตัดสินใจอัตโนมัติเมื่อเกิดข้อผิดพลาดขึ้น และจะไปยังส่วนของโปรแกรมที่มีฟังก์ชัน catch ที่เหมาะสม ไลบรารี่สามารถใช้ได้โดยการ include std standard
<exception>
มายังโปรแกรม
ไลบรารี่มาตรฐานของ Exceptions ในภาษา C++ แสดงดังรายการข้างล่าง:
Exception | Description |
---|---|
bad_alloc | thrown by new on allocation failure |
bad_cast | thrown by dynamic_cast when it fails in a dynamic cast |
bad_exception | thrown by certain dynamic exception specifiers |
bad_typeid | thrown by typeid |
bad_function_call | thrown by empty function objects |
bad_weak_ptr | thrown by shared_ptr when passed a bad weak_ptr |
logic_error | error related to the internal logic of the program |
runtime_error | error detected during runtime |
Exception มาตรฐานทั้งหมดในภาษา C++ นั้นถูกสืบทอดมาจากคลาส
exception
ดังนั้นเราสามารถตรวจจับ Exception มาตรฐานได้โดยใช้คลาสนี้เป็นพารามิเตอร์ในบล็อคคำสั่ง catch
ได้ มาดูตัวอย่าง// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;
int main()
{
try
{
int* myarray= new int[1000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}
ในตัวอย่าง เป็นโปรแกรมในการตรวจจับข้อผิดพลาดที่เกิดจากการจองพื้นที่หน่วยความจำเกิดความผิดพลาด ซึ่งจะ throw
bad_alloc
exception ขึ้น และเราได้จัดการ Exception ในบล็อคของคำสัง catch
และใช้ฟังก์ชัน what()
สำหรับชื่อของ Exception
ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ Exception ในภาษา C++ เราได้พูดถึงการจัดการ Exception ที่เกิดขึ้นด้วยคำสั่ง
throw
และการจัดการ Exception มาตรฐาน ซึ่งมันเป็นวิธีที่เราจะทำให้โปรแกรมของเรามีประสิทธิภาพและยืดหยุ่นกับข้อผิดพลาดต่างๆ ได้ดีที่สุด