Exception handling
Exception handling là mt tính năng mi được gii thiu bi chun ANSI-
C++. Nếu bn s dng mt trình biên dch C++ không tương thích vi chun
ANSI C++ thì bn không th s dng tính năng này.
Trong sut quá trình phát trin mt chương trình, có th có mt s trường hp mà
mt s đon mã chy sai do truy xut đến nhng tài nguyên không tn ti hay vượt
ra ngoài khong mong mun...
Nhng loi tình hung bt thường này được nm trong cái được gi là exceptions
và C++ đã va tích hp ba toán t mi để x lý nhng tình hung này: try, throw
catch.
Dng thc s dng như sau:
try {
// đon mã cn th
throw exception;
}
catch (type exception)
{
// đon được thc hin trong trường hp có li
}
Nguyên tc hot động:
- Đon mã nm trong khi try được thc hin mt cách bình thường. Trong
trường hp có li xy ra, đon mã này phi s dng t khoá throw và mt tham
s để báo li. Kiu tham s này mô t chi tiết hoá li và có th là bt kì kiu hp l
nào.
- Nếu có li xy ra, nếu lnh throw đã được thc hin bên trong khi try, khi
catch s được thc hin và nhn tham s được truyn bi throw.
Ví d:
// exceptions
#include <iostream.h>
int main () {
Exception: Out of range
char myarray[10];
try
{
for (int n=0; n<=10;
n++)
{
if (n>9) throw "Out
of range";
myarray[n]='z';
}
}
catch (char * str)
{
cout << "Exception: "
<< str << endl;
}
return 0;
}
Trong ví d này, nếu bên trong vòng lp mà n ln hơn 9 thì mt li s được thông
báo vì myarray[n] trong trường hp đó có th tr đến địa ch ô nh không tin
cy. Khi throw được thc hin, khi try ngay lp tc kết thúc và mi đối tượng
được to bên trong khi try b phá hu. Sau đó, quyn điu khin được chuyn
cho khi catch tương ng (ch được thc hin trong nhng tình hung như thế
này). Cui cùng chương trình tiếp tc ngay sau khi, trong trường hp này:
return 0;.
Cú pháp được s dng bi throw tương t vi return: Ch có mt tham s
không cn đặt nó nm trong cp ngoc đơn.
Khi catch phi nm ngay sau khi try không được có đon mã nào nm
gia chúng. Tham scatch chp nhn có th là bt kì kiu d liu hp l
nào. Hơn na, catch có th được quá ti để có th chp nhn nhiu kiu d liu
khác nhau. Trong trường hp này khi catch được thc hin là khi phù hp vi
kiu ca tham s được gi đến bi throw:
// exceptions: multiple
catch blocks
#include <iostream.h>
int main () {
Exception: index 10 is out
of range
try
{
char * mystring;
mystring = new char
[10];
if (mystring == NULL)
throw "Allocation
failure";
for (int n=0; n<=100;
n++)
{
if (n>9) throw n;
mystring[n]='z';
}
}
catch (int i)
{
cout << "Exception: ";
cout << "index " << i
<< " is out of range" <<
endl;
}
catch (char * str)
{
cout << "Exception: "
<< str << endl;
}
return 0;
}
đây có th có hai trường hp xy ra:
1. Khi d liu 10 kí t không th được cp phát (gn như là chng bao gi
xy ra nhưng không có nghĩa là không th): li này s b chn bi catch
(to char * str).
2. Ch s cc đại ca mystring đã b vượt quá: li này s b chn bi
catch (int i), since parameter is an integer number.
Chúng ta có th định nghĩa mt khi catch để chn tt c các exceptions mà
không ph thuc vào kiu được dùng để gi throw. Để làm vic này chúng ta
phi viết du ba chm thay vì kiu và tên s tham s:
try {
// code here
}
catch (...) {
cout << "Exception occurred";
}
Còn có th lng các khi try-catch vào các khi try khác. Trong trường hp
này, mt khi catch bên trong có th chuyn tiếp exception nhn đưc cho khi
bên ngoài, để làm vic này chúng ta s dng biu thc throw; không có tham
s. Ví d:
try {
try {
// code here
}
catch (int n) {
throw;
}
}
catch (...) {
cout << "Exception occurred";
}
Exception không b chn
Nếu mt exception không b chn bi bt kì lnh catch nào vì không có lnh nào
có kiu phù hp, hàm đặc bit terminate s được gi.
Hàm này đã được định nghĩa sn để chm dt chương trình ngay lp tc và hin
thc thông báo li "Abnormal termination". Dng thc ca nó như sau:
void terminate();
Nhng exceptions chun
Mt s hàm thuc thư vin C++ chun gi các exceptions mà chúng ta có th chn
nếu chúng ta s dng mt khi try. Nhng exceptions này đưc gi đi vi kiu
tham s là mt lp tha kế t std::exception. Lp này
(std::exception) được định nghĩa trong file header C++ chun
<exception>được dùng làm mu cho h thng phân cp các exception
chun:
exception
bad_alloc (gi bi new)
bad_cast (gi bi dynamic_cast khi tht bi vi
mt kiu tham chiếu)
bad_exception (được gi khi mt exception không phù
hp vi lnh catch nào)
bad_typeid (gi bi typeid)
logic_error
d
i
l
o
o
r
u
omain_error
nvalid_argum
ent
ength_error
ut_of_range
runtime_error
verflow_erro
r
ange_error
nderflow_err
or
ios_base::failu
re (gi bi ios::clear)
Bi vì đây là mt h thng phân lp có th bc, nếu bn s dng mt khi catch
để chn bt kì mt exception nào nm trong h thông này bng cách s dng tham
s biến (thêm mt du & vào phía trước tên ca tham s) bn s chn được tt c
các exception tha kế (lut tha kế trong C++)
Ví d dưới đây chn mt exception có kiu bad_typeid (được tha kế t
exception), li này được to ra khi mun biết kiu ca mt con tr null.
// Nhng exception chun
#include <iostream.h>
#include <exception>
#include <typeinfo>
class A {virtual f() {};
};
int main () {
try {
A * a = NULL;
typeid (*a);
}
Exception: Attempted
typeid of NULL pointer