BAB
9.
Penanganan
Eksepsi
9.1 Pengantar:
Klausa try, throw, dan catch
Dalam C++, penanganan eksepsi dikelola dengan memanfaatkan tiga katakunci,
yaitu try, throw, dan catch. Programer
perlu mengidentifikasi di bagian program mana sebuah eksepsi paling mungkin
bisa terjadi. Sebagai contoh, bagian program dimana program melakukan pembacaan
masukan dari user adalah di mana tempat paling mungkin terjadinya error ketika
user memasukkan data yang salah. Contoh yang lain adalah saat pembagian
integer. Eksepsi bisa terjadi ketika penyebut bernilai nol. Statemen-statemen
semacam itu perlu ditempatkan di dalam sebuah blok try. Blok try diawali dengan katakunci try yang diikuti dengan statemen-statemen yang ditempatkan di dalam
kurung kurawal { dan }. Blok try,
umumnya, memuat kondisi-kondisi seleksi untuk nilai-nilai variabel yang mungkin
bisa menyebabkan terjadinya eksepsi. Ini disebut dengan mekanisme deteksi. Jika
sebuah eksepsi dideteksi, maka eksepsi itu akan dilemparkan menggunakan katakunci
throw seperti diilustrasikan pada
kode berikut.
try //blok
try
{
statemen_statemen;
throw tipe_eksepsi;
//jika eksepsi dideteksi, eksepsi akan
dilempar
}
catch (tipe_eksepsi1) //blok catch pertama
{
statemen_statemen;
}
catch(tipe_eksepsi2) //blok catch kedua
{
statemen_statemen;
}
Perhatikan bahwa segmen throw
diikuti oleh satu atau lebih blok catch.
Setiap blok catch diawali dengan
katakunci catch yang diikuti dengan
kurung () yang memuat tipe data blok catch,
yang kemudian diikuti dengan statemen-statemen blok catch yang diapit di antara kurung kurawal { dan }. Setiap blok catch memiliki tipe yang berbeda untuk
ditangkap. Di sini, tipe mengacu pada salah satu dari tipe-tipe fundamental
seperti int, float, double, atau char, atau tipe-tipe yang didefinisikan
oleh user seperti nama kelas dari objek yang dilempar. Pemilihan dari blok catch tertentu tergantung pada hasil
dari kesesuaian tipe yang dilempar dengan tipe dari blok catch. Jadi, tipe blok catch
tidak boleh sama. Proses ini diilustrasikan pada Gambar 9.1.
GAMBAR 9.1 Ilustrasi dari try, throw, dan catch
Program berikut mengilustrasikan eksepsi yang terjadi ketika pembagian nol
dilakukan.
Program 9.1 Mengilustrasikan aplikasi
dari try, throw, dan catch
|
|
|
#include<iostream>
using namespace std;
int main ()
{
int
A, B;
double
D;
cout<<"Masukkan dua nilai:
";
cin>> A>>B;
try //blok try
{
if(
B == 0)
throw
B; //melempar eksepsi
else
{
D = A/double(B);
cout<<"D =
"<<D<<endl;
}
} //akhir dari blok try
catch
(int C) //blok penanganan eksepsi diawali di sini
{
cout<<"Anda memasukkan B = 0, masukkan nilai
lain"<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 4 0
Anda memasukkan
B = 0, masukkan nilai lain
|
Perlu diketahui bahwa int C
adalah variabel lokal dari blok catch.
Proses penangkapan eksepsi bersifat sensitif terhadap tipe. Blok penangkapan
eksepsi hanya akan menangkap tipe dari apa yang dilempar yang sesuai dengan
tipe yang dideklarikan di dalam blok catch.
Blok try bisa saja diikuti oleh
sejumlah blok catch, masing-masing
dengan tipe yang berbeda. Jika tipe dari apa yang dilempar dan tipe dari apa
yang dideklarasikan pada blok catch
berbeda, maka blok catch tersebut
akan dilompati. Pada dasarnya, penamaan variabel, seperti C, pada program 9.1
adalah sesuatu yang tidak perlu. Anda cukup hanya menuliskan statemen tersebut
sebagai catch(int). Itu adalah tipe
dari variabel yang dilemparkan. Program berikut merupakan contoh lain yang
mengilustrasikan ketika tipe objek yang dilempar adalah double. Jadi, blok catch
dengan argumen double lah yang akan
menanganinya.
Program 9.2 Mengilustrasikan bahwa tipe eksepsi yang dilempar
harus sesuai dengan tipe dari blok catch
|
|
|
#include<iostream>
using namespace std;
int main ()
{
int
A ;
double
B, D ;
cout<<"Masukkan dua nilai:
";
cin>>A>>B;
try
//blok try
{
if(B
== 0.0)
throw
B; //melempar eksepsi bertipe double
else
{
D = A/B;
cout<<"D =
"<<D<<endl;
}
} //akhir dari blok try
catch(int) //blok
penanganan eksepsi untuk int
{
cout<<"Eksepsi tipe
\"int\" ditangkap."<<endl;
}
catch(double) //blok penanganan eksepsi untuk double
{
cout<<"Eksepsi tipe
\"double\" ditangkap."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 5 0
Eksepsi tipe
"double" ditangkap.
|
Program 9.3 Mengilustrasikan bahwa ketika tidak ada tipe dari blok
catch yang cocok dengan tipe yang dilempar, program akan berhenti secara
tidak normal
|
|
|
#include<iostream>
using namespace std;
int main ()
{
int
A;
double
B, D;
char
ch = 'C';
cout<<"Masukkan dua nilai:
";
cin>>A>>B;
try
//blok try
{
if(B
== 0.0)
throw
ch; //melempar tipe char
else
{
D = A/B;
cout<<"D =
"<<D<<endl;
}
} //akhir dari blok try
catch
(int) //blok penanganan eksepsi untuk int
{
cout<<"Eksepsi tipe
\"int\" ditangkap."<<endl;
}
catch(double) //blok penanganan eksepsi untuk double
{
cout<<"Eksepsi tipe
\"double\" ditangkap."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 5 0
abnormal
program termination.
|
Pada program tersebut, tipe dari eksepsi yang dilempar adalah char, sedangkan tipe dari apa yang
ditangkap adalah int dan double. Jadi, tidak satupun dari kedua
tipe dari blok catch cocok dengan
tipe eksepsi. Pada kasus semacam itu, fungsi abort() akan dipanggil untuk menutup program. Program juga
menunjukkan bahwa tipe eksepsi yang dilempar tidak harus sama dengan tipe
variabel yang terlibat di dalam eksepsi. Program berikut menunjukkan bahwa
eksepsi yang dilempar adalah sebuah objek kelas. Pada kasus itu, nama kelas
adalah tipe eksepsi yang dilempar. Ketika sebuah objek kelas dilempar, maka
tipe eksepsi adalah nama dari kelas itu.
Program 9.4 Mengilustrasikan bahwa eksepsi yang dilempar adalah
sebuah objek kelas
|
|
|
#include<iostream>
using namespace std;
class Basis //kelas Basis didefinisikan
{ };
int main()
{
Basis obj_basis ; //obj_basis adalah objek
dari kelas Basis
int
A;
double
B, D;
char
ch = 'C';
cout<<"Masukkan dua nilai:
";
cin>> A>>B;
try
//blok try
{
if(B
== 0.0)
throw
obj_basis; //melempar sebuah objek dari kelas Basis
else
{
D = A/B ;
cout<<"D =
"<<D<<endl;
}
} //akhir dari blok try
catch
(int) //blok penanganan eksepsi
untuk int
{
cout<<"Eksepsi tipe
\"int\" ditangkap."<<endl;
}
catch(Basis)
//blok penanganan eksepsi untuk kelas Basis
{
cout<<"Eksepsi tipe
\"Basis\" ditangkap."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 5 0
Eksepsi tipe
"Basis" ditangkap.
|
Pada program berikut, sebuah kelas dengan Kecuali didefinisikan. Statamen throw dipakai untuk melemparkan sebuah objek Kec dari kelas Kecuali.
Pada blok catch, tipe sama, yaitu
Kecuali, tetapi objek sekarang adalah Kecd.
Eksepsi ditangkap karena tipe sama. Jika lebih dari satu eksepsi yang bertipe
sama dilemparkan, maka hanya satu blok catch
yang diperlukan untuk menangkapnya. Untuk membedakan dua eksepsi, statemen
seleksi perlu disediakan di dalam blok catch
sehingga penanganan eksepsi dapat dilakukan sesuai dengan yang diinginkan.
Program 9.5 Mengilustrasikan bahwa beberapa eksepsi dapat
dilemparkan dari blok try yang sama
|
|
|
#include<iostream>
using namespace std;
class Kecuali{
public:
void
Tampil1( )
{
cout<<"Terjadi sebuah eksepsi.\nNilai yang dimasukkan untuk A
adalah negatif\n";
cout <<"Msukkan nilai
positif.\n";
}
void
Tampil2 ()
{
cout<<"Nilai B yang
dimasukkan adalah nol. \n";
cout<<"Masukkan sebuah
nilai lebih besar dari nol.\n";
}
};
int main ()
{
Kecuali Kec;
int
A, B ;
double
D;
cout<<"Masukkan dua nilai:
";
cin>> A>>B;
try
{
if
(B == 0)
throw
Kec ;
else
if
(A < 0)
throw Kec;
else
{
D = A/ double(B);
cout<<"D =
"<<D<<end
}
}
catch
(Kecuali Kecd)
{
if
(A < 0)
Kecd.Tampil1();
if
(B == 0)
Kecd.Tampil2();
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 4 0
Nilai B yang
dimasukkan adalah nol.
Masukkan sebuah
nilai lebih besar dari nol.
|
Blok try dapat memiliki lebih
dari satu statemen throw. Selain itu, blok try
juga dapat diikuti oleh lebih dari satu blok catch tetapi argumen-argumennya harus berbeda tipe. Satu blok catch tidak bisa memiliki dua tipe
berbeda sebagai argumennya. Misalnya, catch(int
A, double B) akan menghasilkan error kompilasi. Pada program berikut, dua
tipe yang berbeda dilemparkan dari blok try
yang sama, dan ia memerlukan dua blok catch yang berbeda, satu untuk tiap tipe.
Program 9.6 Mengilustrasikan bahwa beberapa eksepsi dapat
dilemparkan dari blok try yang sama, yang memerlukan dua blok catch yang
berbeda
|
|
|
#include<iostream>
using namespace std;
int main ()
{
int
A;
double
D, B;
cout<<"Masukkan dua nilai:
";
cin>>A>>B;
try
{
if
(B == 0)
throw
B;
if
(A > 50)
throw
A;
else
{
D = A/ B;
cout<<"D =
"<<D<<endl;
}
}
catch
(double C)
{
cout<<"Anda masukkan B = 0,
silahkan masukkan nilai lain."<<endl;
}
catch
(int E )
{
cout<<"Silahkan masukkan
nilai lain yang kurang dari 50 untuk A."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 75 5
Silahkan
masukkan nilai lain yang kurang dari 50 untuk A.
|
Di dalam blok try yang sama,
Anda bisa memiliki beberapa statemen throw.
Jika semua eksepsi yang dilemparkan bertipe sama, maa hanya diperlukan satu
blok catch untuk menangkapnya. Untuk
informasi bagi user tentang eksepsi mana yang ditangkap, sejumlah statemen
seleksi perlu dicantumkan di dalam blok catch
tersebut. Seperti yang terjadi pada statemen-statemen seleksi, jika satu
statemen diseleksi, maka statemen-statemen lain akan diabaikan.
9.2 Menangkap
Semua Tipe Eksepsi
Untuk menangkap semua tipe eksepsi yang dilemparkan, kode catch(…) dapat digunakan. Perhatikan
bahwa hanya ada tiga titik di dalam kurung tersebut. Program berikut
mengilustrasikan catch(…).
Program 9.7 Mengilustrasikan penggunaan catch(…) untuk menangkap
semua eksepsi
|
|
|
#include<iostream>
using namespace std;
class Basis
{ };
int main ()
{
Basis obj_basis ;
int
A;
double
B, D;
char
ch;
cout<<"Masukkan sebuah integer,
sebuah double, dan sebuah karakter: ";
cin>>A>>B>>ch;
try
{
if(B
== 0.0)
throw
obj_basis;
if
(A > 50)
throw
A;
if(ch
!= 'Z')
throw
ch;
else
{
D = A/double(B);
cout <<"D =
"<<D<<endl;
}
} //akhir dari blok try
catch
(...) //blok penanganan eksepsi diawali di sini
{
if
(A >50)
cout<<"Eksepsi pada int
ditangkap."<<endl;
if
(B==0)
cout<<"Eksepsi pada Basis
ditangkap."<<endl;
if(ch
!= 'Z')
cout<<"Eksepsi pada char
ditangkap."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
integer, sebuah double, dan sebuah karakter: 30 6.5 Z
D = 4.61538
Masukkan sebuah
integer, sebuah double, dan sebuah karakter: 56 0 H
Eksepsi pada
int ditangkap.
Eksepsi pada
Basis ditangkap.
Eksepsi pada
char ditangkap.
|
9.3 Fungsi
untuk Menangani Eksepsi
Runtun try-throw dan catch bisa
ditempatkan ke dalam suatu fungsi. Adalah lebih mudah untuk memanggil fungsi di
dalam program utama. Program berikut mengilustrasikannya.
Program 9.8 Mengilustrasikan aplikasi dari fungsi penanganan
eksepsi
|
|
|
#include<iostream>
using namespace std;
void Uji(int A, double B, char ch)
{
try
{
if
(A > 50.0)
{
cout <<"A berada di luar
rentang"<<endl;
throw
A;
}
if
(B == 0)
{
cout <<"B sama dengan
nol"<<endl;
throw
B;
}
if
(ch != 'D')
{
cout<<"ch tidak sama
dengan D"<<endl;
throw
ch;
}
else
cout<<"Semua berada di dalam rentang. Tidak ada eksepsi yang dilempar." <<endl;
}
catch
(...)
{
cout<<"Menangkap sebuah
eksepsi"<<endl;
}
}
int main ()
{
int
A;
double
B;
char
ch;
cout<<"Tulislah nilai A, b, dan
ch: ";
cin>>A>>B>>ch;
Uji(A,B,ch); //fungsi uji untuk try, throw dan catch
return
0;
}
|
KELUARAN
|
|
Tulislah nilai
A, b, dan ch: 50 4.6 F
ch tidak sama
dengan D
Menangkap
sebuah eksepsi
Tulislah nilai
A, b, dan ch: 65.5 40.5 F
A berada di
luar rentang
Menangkap
sebuah eksepsi
|
9.4 Spesifikasi
Eksepsi
C++ dapat dipakai oleh user untuk mendeklarasikan sejumlah eksepsi yang
dapat dilempar oleh sebuah fungsi. Spesifikasi eksepsi pada dasarnya imbuhan
pada kepala fungsi yang biasa (normal). Imbuhan tersebut terdiri-dari katakunci
throw, yang diikuti, di dalam
kurung, daftar tipe eksepsi. Definisi fungsi dengan sebuah spesifikasi eksepsi
memiliki format berikut:
tipe
pengenal_fungsi (daftar_argumen) throw (daftar_tipe_eksepsi) //kepala
fungsi
{statemen_statemen;}
//tubuh fungsi
Pada definisi di atas, kata pertama, tipe,
adalah tipe data dari nilai balik yang dihasilkan fungsi. Kata tersebut diikuti
oleh nama fungsi yang kemudian diikuti oleh daftar argumen di dalam kurung dan
kemudian imbuhan yang memuat katakunci throw
yang diikuti oleh daftar tipe eksepsi di dalam kurung. Tipe fungsi tidak
dipengaruhi oleh imbuhan. Daftar tipe eksepsi dan daftar argumen bersifat
opsional (boleh tidak ada). Jadi, perhatikan tiga kasus berikut:
a.
void Fungsi1() throw () //daftar_tipe_eksepsi
kosong, tidak bisa melempar eksepsi.
b. void Fungsi2() throw(X, Y, Z) //hanya
dapat melempar tipe eksepsi X, Y, dan Z.
c.
void Fungsi3() //dapat melempar sembarang tipe eksepsi
Jika fungsi melemparkan sebuah eksepsi yang tidak ada di dalam daftar_tipe_eksepsi, maka fungsi unexpected() akan dipanggil. Aksi
default dari fungsi unexpected()
adalah untuk memanggil fungsi abort()
yang menghentikan program.
Fungsi dengan imbuhan throw()
tidak dapat melemparkan eksepsi apapun dan jika ia melakukannya, maka fungsi unexpected() akan dipanggil dan program
akan dihentikan. Sama halnya, jika fungsi dengan daftar_tipe_eksepsi, (X, Y, Z), melemparkan sebuah eksepsi selain
X, Y, atau Z, maka program akan dihentikan. Opsi ketiga, void Fungsi3(), dapat melemparkan sembarang tipe eksepsi.
Program 9.9 Mengilustrasikan spesifikasi
eksepsi
|
|
|
#include<iostream>
using namespace std;
void FEksepsi (int j) throw () //tidak dapat melemparkan eksepsi apapun
{
if
(j== 1)
throw
j;
if
(j == 2)
throw
char();
if
(j==3)
throw
double();
}
int main ()
{
int
n;
cout<<"Masukkan sebuah nilai
antara 1 sampai 3:";
cin>>n ;
try{
FEksepsi(n);
} //akhir blok try
catch(int) //blok penanganan eksepsi
diawali di sini
{
cout<<"Statemen throw int
ditangkap"<<endl;
}
catch(double)
{
cout<<"Statemen throw double
ditangkap"<<endl;}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
nilai antara 1 sampai 3:2
abnormal
program termination
|
Program 9.10 Mengilustrasikan bahwa jika tipe eksepsi yang
dilemparkan tidak ada di dalam spesifikasi eksepsi, maka program akan
dihentikan
|
|
|
#include<iostream>
using namespace std;
//fungsi
berikut dapat melempar int atau double
void FEksepsi(int j) throw(int, double)
{
if
(j== 1)
throw
j;
if
(j == 2)
throw
'D';
if(j==3)
throw
0.8;
}
int main ()
{
int
n;
cout<<"Masukkan sebuah nilai
antara 1 sampai 3: ";
cin>>n ;
try{
FEksepsi(n);
} //akhir blok try
catch(int) //blok penanganan eksepsi
diawali di sini
{
cout<<"Statemen throw int
ditangkap"<<endl;
}
catch(double)
{
cout<<"Statemen throw double
ditangkap"<<endl;}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
nilai antara 1 sampai 3: 2
abnormal
program termination
|
Program dijalankan dan nilai 2 dimasukkan. Ini berkaitan dengan pelemparan
eksepsi bertipe char yang tidak ada
di dalam daftar spesifikasi. Oleh karena itu, program dihentikan.
Pada program berikut, eksepsi yang dilemperkan berada di dalam daftar
spesifikasi eksepsi.
Program 9.11 Mengilustrasikan implementasi dari
eksepsi-eksepsi terdaftar
|
|
|
#include<iostream>
using namespace std;
void
FungsiSpesifikasi(int j) throw (int, double, char)
{
if
(j == 1)
throw
j;
if
(j ==2)
throw
0.6;
if
(j == 3)
throw
'H';
}
int main ()
{
try
{
int
A (4);
if (A != 3)
FungsiSpesifikasi(1);
}
catch
(int) //blok penanganan eksepsi
diawali di sini
{
cout<<"Ekspesi pada int
ditangkap"<<endl;
}
try
{ //blok try
double
B (6.6);
if
(B!=7)
FungsiSpesifikasi(2);
}
catch
(double) //blok penanganan eksepsi
diawali di sini
{
cout<<"Ekspesi pada double
ditangkap"<<endl;
}
try
{
char
ch = 'C';
if
(ch != 'H')
FungsiSpesifikasi(3);
}
catch(char)
{
cout<<"Ekspesi pada char
ditangkap"<<endl;
}
return
0;
}
|
KELUARAN
|
|
Ekspesi pada
int ditangkap
Ekspesi pada
double ditangkap
Ekspesi pada
char ditangkap
|
9.5 Melempar-Ulang
Eksepsi
Sebuah eksepsi dapat ditangkap oleh suatu blok penanganan eksepsi dan
hanya secara parsial ditangani. Programer bisa melemparkan ulang eksepsi
tersebut sehingga dapat ditangani oleh mekanisme catch sebelah luar. Untuk kasus semacam itu, kode berikut perlu
dicantumkan di dalam blok catch:
throw;
Kode ini akan melempar ulang tipe eksepsi yang sama sehingga ia dapat
ditangani oleh blok catch sebelah
luar. Eksepsi yang dilempar-ulang tidak ditangkap oleh blok catch yang sama. Eksepsi itu ditangkap
oleh blok catch sebelah luar.
Program berikut mengilustrasikan pelemparan-ulang eksepsi.
Program 9.12 Mengilustrasikan implementasi dari
eksepsi-eksepsi terdaftar
|
|
|
#include<iostream>
using namespace std;
void LemparUlang(int A) //definisi dari fungsi
LemparUlang()
{
try
{
int
B;
cout<<"Masukkan sebuah nilai
positif: ";
cin>> B ;
if
(B<=0)
throw
B;
}
catch
(int)
{
cout<<"Blok catch ini di
dalam fungsi LemparUlang."<<endl;
throw; //LemparUlang kedua
}
}
int main ()
{
try{
try
{
LemparUlang(6);
}
catch(int)
{
cout<<"Blok catch ini
adalah blok catch dalam di dalam main."<<endl;
throw;
// LemparUlang kedua
}
}
catch(int)
{
cout<<"Blok catch ini adalah
blok catch luar di dalam main."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
nilai positif: -5
Blok catch ini
di dalam fungsi LemparUlang.
Blok catch ini
adalah blok catch dalam di dalam main.
Blok catch ini
adalah blok catch luar di dalam main.
|
9.6 Kelas-Kelas
Eksepsi Pustaka Standar C++
Ada sejumlah besar kelas di dalam pustaka standar C++ yang bisa menangani
eksepsi. Gambar 9.2 menunjukkan hierarki dari kelas-kelas yang menangani
eksepsi di dalam C++. File header <exception>
mendefinisikan eksepsi kelas basis. Sejumlah kelas diderivasi dari kelas basis.
Kelas-kelas tersebut termasuk logic_error,
runtime_error, bac_alloc, bad_cast, bad_typid, dan bad_exception. Ada tiga kelas yang diderivasi dari kelas logic_error, yaitu kelas out_of_range, length_error, dan invalid_argument.
Kelas-kelas yang berkaitan dengan runtime error dan logic error didefinisikan
di dalam file header <stdexcept>.
Empat kelas, yaitu bad_alloc, bad_cast, bad_typeid, dan bad_exception
adalah tipe eksepsi yang dilemparkan oleh operator-operator. Kelas exceptio
juga mendefinisikan sebuah fungsi virtual what()
yang didefinisikan-ulang oleh semua kelas terderivasi untuk menyampaikan pesan
tertentu.
Sejumlah kelas yang berkaitan dengan eksepsi dan kelas-kelas terderivasi
diilustrasikan pada Gambar 9.2. Tabel 9.1 mengelaborasi sejumlah kelas eksepsi
tersebut.
GAMBAR 9.2 Kelas-kelas eksepsi di dalam pustaka
standar C++
TABEL 9.1 Sejumlah kelas eksepsi di dalam pustaka standar C++
Kelas
|
Penjelasan
|
overflow_error
|
Eksepsi ini berkaitan dengan sebuah nilai yang nilainya
terlalu besar untuk komputer.
|
underflow_error
|
Eksepsi ini berkaitan dengan sebuah nilai yang nilainya
terlalu kecil untuk komputer.
|
bad_alloc
|
Eksepsi yang dilemparkan oleh operator new pada kasus pengalokasian memori
yang gagal (memori tidak tersedia).
|
bad_cast
|
Eksepsi ini dilemparkan oleh dynamic_cast jika tidak berhasil.
|
bad_typeid
|
Eksepsi ini dilemparkan oleh operator typeid() jika tidak berhasil.
|
bad_exception
|
Jika sebuah eksepsi yang tidak terdaftar di dalam
spesifikasi eksepsi terjadi, maka eksepsi bad_exception akan dilemparkan oleh
fungsi unexpected().
|
invalid_argument
|
Sebagai contoh, sebuah nilai negatif untuk akar kuadrat
adalah argumen yang tak valid.
|
length_error
|
Mengindikasikan bahwa sebuah panjang lebih besar dari yang
ditetapkan untuk objek yang digunakan.
|
out_of_range
|
Mengindikasikan ketika sebuah nilai melebihi rentang nilai
yang diijinkan.
|
Program berikut merupakan sebuah ilustrasi dari aplikasi atas kelas
eksepsi standar.
Program 9.13 Mengilustrasikan aplikasi dari overflod_error
|
|
|
#include <iostream>
#include <stdexcept>
using namespace std;
double Resiprokal(double A) throw (overflow_error)
{
cout<<"Tulislah sebuah nilai
sangat kecil :";
cin>> A;
if(A
< 0.000001)
throw
overflow_error("Resiprokal terlalu besar.");
return
1/A ;
}
int main ()
{
try
{
double
B =0.0;
cout<<"Resiprokal dari B =
"<<Resiprokal(B)<<endl;
}
catch
(exception & x)
{
cout<<"Eksepsi ->
"<< x.what()<<endl;
}
return
0;
}
|
KELUARAN
|
|
Tulislah sebuah
nilai sangat kecil :0.000000001
Eksepsi ->
Resiprokal terlalu besar.
Tulislah sebuah
nilai sangat kecil :0.0005
Resiprokal dari
B = 2000
|
Program berikut mengilustrasikan pelemparan eksepsi invalid_argument.
Program 9.14 Mengilustrasikan aplikasi dari fungsi standar
dari kelas <exception>
|
|
|
#include<iostream>
using namespace std;
#include<cmath>
#include<exception>
double AkarKuadrat(int n) throw (invalid_argument)
{
if
(n < 0)
throw
logic_error("invalid_argument untuk akar kuadrat");
return
sqrt(n);
}
int main()
{
int
m;
cout<<"Masukkan sebuah nilai
integer: ";
cin>>m;
try
{
cout<<"Akar kuadrat dari
"<<m<<" adalah
"<<AkarKuadrat(m)<<endl;
}
catch
(exception& eksp)
{
cout<<eksp.what()<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
nilai integer: -5
invalid_argument
untuk akar kuadrat
|
9.7 Fungsi
set_terminate()
Ketika sebuah eksepsi dilemparkan dan tidak ada blok catch yang
menangkapnya, maka aksi defaultnya adalah fungsi terminate() dipanggil, yang secara default memanggil fungsi abort() untuk menghentikan program.
Namun, programer dapat memiliki opsi kedua dengan mendefinisikan fungsi terminate() dan dengan medaftarkannya
di dalam program menggunakan fungsi set_terminate().
Lihat program berikut untuk ilustrasi.
Program 9.15 Mengilustrasikan aplikasi dari fungsi
set_terminate()
|
|
|
#include<iostream>
#include<stdexcept>
using namespace std;
void berhenti()
{
cout<<"Sebuah eksepsi telah
terjadi."<<endl;
cout<<"Program
dihentikan."<<endl;
exit(1);
}
int main ()
{
set_terminate(berhenti);
try
{
int
A;
cout<<"Masukkan sebuah nilai yang lebih kecil dari 60:
";
cin >> A;
if
(A > 60)
throw
A;
cout<<"Nilai yang dimasukkan
adalah "<<A<<endl;
}
catch
(double)
{
cout<<"Nilai berada di luar
rentang."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan sebuah
nilai yang lebih kecil dari 60: 76
Sebuah eksepsi
telah terjadi.
Program
dihentikan.
|
LATIHAN
1.
Apa itu eksepsi
di dalam C++?
2.
Jelaskan try, throw, dan catch yang
berkaitan dengan eksepsi.
3.
Apa yang Anda
pahami tentang spesifikasi eksepsi?
4.
Berikan sebuah
contoh dari blok try.
5.
Apa yang harus
cocok antara statemen throw dan blok
catch sehingga eksepsi dapat
ditangani?
6.
Apa kegunaan dari fungsi set_terminate()?
7.
Eksepsi manakah yang dilemparkan oleh
operator new?
8.
Tuliskan sebuah program kecil untuk
mengilustrasikan bagaimana mekanisme try,
throw, dan catch bekerja.
9.
Apakah kode untuk menangkap semua tipe
eksepsi?
10.
Tulislah sebuah program untuk
menunjukkan bahwa jika objek kelas terderivasi dilemparkan, maka blok catch dengan tipe kelas basis dapat
menangkapnya.
Jawaban:
Program 9.16 Mengilustrasikan bahwa jika objek kelas terderivasi dilemparkan,
maka blok catch dengan tipe kelas basis dapat menangkapnya
|
|
|
#include<iostream>
using namespace std;
class Basis //kelas Basis didefinisikan
{ };
class Terderivasi :
public Basis //kelas Terderivasi didefinisikan
{};
int main ()
{
Basis obj_basis ; //obj_basis adalah objek dari kelas Basis
Terderivasi obj_derivasi; // obj_derivasi adalah objek dari kelas
Terderivasi
int
A;
double
B, D ;
char
ch = 'C';
cout<<"Masukkan dua nilai:
";
cin>> A>>B;
try
//blok try
{
if
(B == 0.0)
throw
obj_derivasi; //melempar sebuah
objek dari kelas Terderivasi
else
{
D = A/B ;
cout<<"D = "<<
D <<endl;
}
} //akhir blok try
catch
(int) //blok penanganan eksepsi
untuk int
{
cout<<"Eksepsi tipe
\"int\" ditangkap."<<endl;
}
catch(Basis)
//blok penanganan eksepsi untuk kelas Basis
{
cout<<"Eksepsi tipe
\"Basis\" ditangkap."<<endl;
}
return
0;
}
|
KELUARAN
|
|
Masukkan dua
nilai: 6.0 0.0
Eksepsi tipe
"Basis" ditangkap.
|
No comments:
Post a Comment