Phô lôc 2: Xö lý lçi
Ph l c 2ụ ụ
X lý l iử ỗ
B t u t phiên b n 3.0, C++ cung c p c ch x lý l i (exception handling) do ng i s d ngắ đầ ừ ả ấ ơ ế ử ỗ ườ ử ụ
i u h nh. Trong ch ng trình có th a ra quy t nh r ng m t phép x lý n o ó b l i b ngđ ề à ươ ể đư ế đị ằ ộ ử à đ ị ỗ ằ
cách s d ng t khoá ử ụ ừ throw. Khi có l i, vi c x lý b ng t v quy n i u khi n s trao tr choỗ ệ ử ị ắ à ề đ ề ể ẽ ả
o n x lý l i m ng i s d ng b t c.đ ạ ử ỗ à ườ ử ụ ắ đượ
1. B y v b t l iẫ à ắ ỗ
Ta l y ví d vi t m t h m tính giá tr c a m t phân s v i u v o l t s v m u s . R cấ ụ ế ộ à ị ủ ộ ố ớ đầ à à ử ố à ẫ ố ắ
r i s n y sinh khi ng i s d ng h m truy n v o cho m u s giá tr b ng 0. gi i quy t tr ngố ẽ ả ườ ử ụ à ề à ẫ ố ị ằ Để ả ế ườ
h p n y, C++ s t ng t o sinh b y l i “g p tr ng h p m u s b ng 0”. Sau ây l ch ngợ à ẽ ự độ ạ ẫ ỗ ặ ườ ợ ẫ ố ằ đ à ươ
trình ví d cho h m tính giá tr phân s có x lý l i. ụ à ị ố ử ỗ
#include <iostream.h>
// l p ki u l i m không có th nh ph n n oớ ể ỗ à à ầ à
class Loi_Chia_0 {};
float GiaTriPS(int ts, int ms){
// phát l i n u m u = 0ỗ ế ẫ
if ( ms==0 ) throw( Loi_Chia_0 );
return float(ts)/ms;
}
void main(){
int ts, ms;
cout << “Tinh gia tri phan so\n”;
cout << “TS = “; cin >> ts;
cout << “MS = “; cin >> ms;
try { // th c hi n có b t l iự ệ ắ ỗ
float gt = GiaTriPS(ts, ms);
cout << “Gia tri PS la: “ << gt;
}
catch ( Loi_Chia_0 ) // b t l i ki u Loi_Chia_0ắ ỗ ể
{
cout << “Loi: Mau so bang 0”;
}
}
Tinh gia tri phan so
TS = 1
-223-
Phô lôc 2: Xö lý lçi
MS = 0
Loi: Mau so bang 0
Ch ng trình n y có hai ph n b y l i v b t l i. H m tính phân s s phát sinh m t b y l iươ à ầ ẫ ỗ à ắ ỗ à ố ẽ ộ ẫ ỗ
b ng t khoá ằ ừ throw khi m u s b ng 0. Phía sau t khoá throw l i t ng thu c l p ph c v b tẫ ố ằ ừ à đố ượ ộ ớ ụ ụ ắ
l i. ây ta s d ng l p ỗ ở đ ử ụ ớ Loi_Chia_0 không có th nh ph n n o bên trong ph c v cho vi c b tà ầ à để ụ ụ ệ ắ
l i n y. Khi m t l i c phát sinh, to n b nh ng l nh ti p theo trong h m x lý b hu b . Trongỗ à ộ ỗ đượ à ộ ữ ệ ế à ử ị ỷ ỏ
thân ch ng trình chính chúng ta s d ng c u trúc ươ ử ụ ấ try... catch... b t l i. H m để ắ ỗ à GiaTriPS cđượ
t trong đặ try, do v y khi nó phát sinh l i (l i lo i Loi_Chia_0 c phát sinh khi m u s truy n v oậ ỗ ỗ ạ đượ ẫ ố ề à
l 0) thì ch ng trình d ng ho t ng v trao quy n i u khi n cho o n mã b t l i n y. Ta ãà ươ ừ ạ độ à ề đ ề ể đ ạ ắ ỗ à đ
dùng catch ( Loi_Chia_0 ) b t l i. Nh v y, khi có m t l i chia 0 thì ch ng trình s in ra dòngđể ắ ỗ ư ậ ộ ỗ ươ ẽ
thông báo “Loi: Mau so bang 0”. Khi trong ch ng trình có m t l i phát sinh m không có o n b tươ ộ ỗ à đ ạ ắ
l i t ng ng thì ch ng trình s t ng k t thúc b t th ng. i u n y s gây tr ng i áng kỗ ươ ứ ươ ẽ ự độ ế ấ ườ Đ ề à ẽ ở ạ đ ể
cho vi c g r i ch ng trình.ệ ỡ ố ươ
M t ch ng trình có th phát sinh nhi u lo i l i khác nhau. Lo i l i phát sinh th hi n ki uộ ươ ể ề ạ ỗ ạ ỗ ể ệ ở ể
l p l i c s d ng trong các l nh ớ ỗ đượ ử ụ ệ throw. Do v y, ta c ng có th s d ng nhi u l n ậ ũ ể ử ụ ề ầ catch b tđể ắ
các lo i l i khác nhau trong m t ch ng trình nh trong ví d sau.ạ ỗ ộ ươ ư ụ
#include <iostream.h>
class Loi_A {};
class Loi_B {};
void PhatLoi(int i){
// neu i khac 0 thi phat Loi_A con khong Loi_B
if (i) throw ( Loi_A );
throw ( Loi_B );
}
void main(){
int i;
cout << “i = “; cin >> i;
try
{
PhatLoi( i );
}
catch ( Loi_A )
{
cout << “Loi loai A”;
}
catch ( Loi_B )
{
cout << “Loi loai B”;
}
}
i = 1
-224-
Phô lôc 2: Xö lý lçi
Loi loai A
i = 0
Loi loai B
Ta c ng có th s d ng ũ ể ử ụ catch(...) b t t t c các lo i l i. L p l i có th có các th nhđể ắ ấ ả ạ ỗ ớ ỗ ể à
ph n gi ng nh l p bình th ng dùng l m các thông s x lý l i khi b t c. Ch ng h n,ầ ố ư ớ ườ để à ố ử ỗ ắ đượ ẳ ạ
trong ch ng trình x lý l i chia 0 trên ta có th thêm v o thu c tính l u l i t s c a phépươ ử ỗ ở ể à ộ để ư ạ ử ố ủ
chia l i dùng in ra khi b t l i.ỗ ắ ỗ
#include <iostream.h>
class Loi_Chia_0{
public:
int ts;
Loi_Chia_0(int t): ts(t) {}
};
float GiaTriPS(int ts, int ms){
if ( ms==0 ) throw( Loi_Chia_0(ts) );
return float(ts)/ms;
}
void main(){
int ts, ms;
cout << “Tinh gia tri phan so\n”;
cout << “TS = “; cin >> ts;
cout << “MS = “; cin >> ms;
try {
float gt = GiaTriPS(ts, ms);
cout << “Gia tri PS la: “ << gt;
}
catch ( Loi_Chia_0 loi )
{
cout << “Loi chia “ << loi.ts << “ cho 0”;
}
}
Tinh gia tri phan so
TS = 1
MS = 0
Loi chia 1 cho 0
-225-
Phô lôc 2: Xö lý lçi
2. Ho t đ ng c a ch ng trình khi m t l i phát sinhạ ộ ủ ươ ộ ỗ
Khi m t l i trong ch ng trình ã b b t thì ch ng trình ti p t c ho t ng bình th ng theoộ ỗ ươ đ ị ắ ươ ế ụ ạ độ ườ
mã l nh x lý l i b t c. Trong m t h m x lý ng i s d ng có th b t l i x y ra v sau óệ ử ỗ ắ đượ ộ à ử ườ ử ụ ể ắ ỗ ả à đ
ti p t c ném nó duy trì l i c a ch ng trình b ng t khoá ế ụ để ỗ ủ ươ ằ ừ throw m không có ki u lo i l ià ể ạ ỗ
phía sau.
#include <iostream.h>
class Loi {};
void PhatLoi(){
throw ( Loi );
}
void BatLoi(){
try {
PhatLoi();
}
catch ( Loi ) {
cout << “Loi da bi bat va duoc nem lai\n”;
throw; // ném l i l i b b tạ ỗ ị ắ
}
}
void main() {
try {
BatLoi();
}
catch ( Loi ) {
cout << “Loi bi bat lai lan hai”;
}
}
Loi da bi bat va duoc nem lai
Loi bi bat lai lan hai
Khi m t l i x y ra m không có m t b t l i n o áp ng thì ch ng trình s k t thúc vộ ỗ ả à ộ ắ ỗ à đ ứ ươ ẽ ế à
tr c khi k t thúc nó s th c hi n h m x lý c xác l p trong câu l nh ướ ế ẽ ự ệ à ử đượ ậ ệ set_terminate.
#include <iostream.h>
class Loi {};
void KetThucLoi(){
cout << “Chuong trinh bi loi va ket thuc bat thuong\n”;
}
void PhatLoi(){
-226-
Phô lôc 2: Xö lý lçi
throw ( Loi );
}
void main(){
// xác l p h m k t thúc b t th ngậ à ế ấ ườ
set_terminate(KetThucLoi);
cout << “Goi ham phat loi ma khong bat\n”;
PhatLoi();
cout << “Ket thuc binh thuong\n”;
}
Goi ham phat loi ma khong bat
Chuong trinh bi loi va ket thuc bat thuong
Trong m t h m x lý ng i x d ng có th xác nh t t c nh ng l i có th x y ra b ng cáchộ à ử ườ ử ụ ể đị ấ ả ữ ỗ ể ả ằ
dùng t khoá ừ throw ng ngay sau khai báo tham s h m v li t kê nh ng l p l i có th x y ra đứ ố à à ệ ữ ớ ỗ ể ả để
trong c p d u ( ). N u không có l p l i n o c li t kê thì hi u r ng h m ó s không có l i. Cònặ ấ ế ớ ỗ à đượ ệ ể ằ à đ ẽ ỗ
n u không có t khoá ế ừ throw thì h m ó có th có b t kì l i n o.à đ ể ấ ỗ à
// h m có th có L i_A ho c L i_Bà ể ỗ ặ ỗ
void fct1() throw(Loi_A, Loi_B);
// h m s không có l i n oà ẽ ỗ à
void fct2() throw();
// h m có th có b t kì lo i l i n oà ể ấ ạ ỗ à
void fct3();
Tr ng h p v i m t h m n o ó tuy ã c xác nh m t s l i có th x y ra, nh ng khiườ ợ ớ ộ à à đ đ đượ đị ộ ố ỗ ể ả ư
ch y l i xu t hi n m t l i không ph i l l i ã xác nh, thì ch ng trình s k t thúc. Tr c khiạ ạ ấ ệ ộ ỗ ả à ỗ đ đị ươ ẽ ế ướ
k t thúc nó s th c hi n phép x lý c a h m c xác l p b ng h m ế ẽ ự ệ ử ủ à đượ ậ ằ à set_unexpected.
#include <iostream.h>
class Loi_A {};
class Loi_B {}
void LoiKhongCho()
{
cout << “Chuong trinh ket thuc vi gap loi khong cho\n”;
}
void PhatLoi() throw(Loi_B){
throw (Loi_A);
}
void main(){
// xác l p h m k t thúc khi g p l i không ch iậ à ế ặ ỗ ờ đợ
set_unexpected(LoiKhongCho);
try {
-227-