Giáo trình Lập trình hướng đối tượng với C++ - 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.
BÉy vµ b¾t lçi
1.
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;
}
-287-
Ng«n ng÷ C++
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
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 );
-288-
Xö lý lçi
}
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
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;
-289-
Ng«n ng÷ C++
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
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>
-290-
Xö lý lçi
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(){
-291-
Ng«n ng÷ C++
cout << “Chuong trinh bi loi va ket thuc bat thuong\n”;
}
void PhatLoi(){
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 {}
-292-
Xö lý lçi
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
{
cout << “Goi ham phat loi\n”;
PhatLoi();
}
catch ( ... ) {
cout << “Loi da bi bat”;
}
}
Goi ham phat loi
Chuong trinh ket thuc vi gap loi khong cho
3. Xö lý lçi trong líp øng dông
Trong môc nµy chóng ta sÏ x©y dùng mét líp øng dông m¶ng ®éng cã kiÓm
so¸t lçi khëi t¹o víi sè phÇn tö nhá h¬n hoÆc b»ng kh«ng vµ lçi truy nhËp phÇn tö
ngoµi chØ sè.
#include <iostream.h>
#include <stdlib.h>
class Loi{
public:
virtual void InLoi()=0;
};
-293-
Ng«n ng÷ C++
// lçi khëi t¹o
class Loi_KT : public Loi {
public:
int spt;
Loi_KT(int n): spt(n) {}
void InLoi() {
cout << “Loi khoi tao voi ” << spt << “ phan tu\n”;
}
};
// loi truy cap
class Loi_TC : public Loi {
public:
int cs;
Loi_TC(int i): cs(i) {}
void InLoi() {
cout << “Loi truy cap chi so ” << cs << “\n”;
}
};
class Array
{
int spt; // so phan tu mang
int *dl; // du lieu cua mang
public:
Array(int n): spt(n) {
if ( spt <= 0 ) throw( Loi_KT(spt) );
dl = new int[spt];
}
~Array() { delete dl; }
int & operator [] (int i){
if ( i<0 || i>=spt ) throw( Loi_TC(i) );
return dl[i];
-294-
Xö lý lçi
}
};
void main(){
try
{
Array a(-3);
a[5] = 10;
}
// bat toan bo loi ke thua tu Loi
catch ( Loi& l )
l.InLoi(); // in loi tuong ung boi
{
}
}
Loi khoi tao voi -3 phan tu
Trong ch-¬ng tr×nh trªn ®· dïng kÜ thuËt ®a h×nh ®Ó t¹o mét líp lçi trõu t-îng
c¬ së cã ph-¬ng thøc in lçi ¶o. C¸c lçi cô thÓ kÕ thõa tõ líp nµy vµ thi hµnh cô thÓ
viÖc in lçi cho nã. Khi b¾t lçi, chØ cÇn b¾t lçi líp c¬ së mét c¸ch tæng qu¸t th× tÊt c¶
c¸c kiÓu lçi trong líp kÕ thõa ®Òu bÞ b¾t. Khi gäi thñ tôc in lçi bÞ b¾t, hÖ thèng sÏ in
®óng lçi cña líp nã thuéc vµo t-¬ng tù nh- tÝnh t-¬ng øng béi.
-295-
Ng«n ng÷ C++
1. BÉy vµ b¾t lçi.............................................................................287
2. Ho¹t ®éng cña ch-¬ng tr×nh khi mét lçi ph¸t sinh.................... 290
3. Xö lý lçi trong líp øng dông..................................................... 293
-296-
Bạn đang xem tài liệu "Giáo trình Lập trình hướng đối tượng với C++ - Xử lý lỗi", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
giao_trinh_lap_trinh_huong_doi_tuong_voi_c_phu_luc_2.pdf

